~ubuntu-branches/ubuntu/wily/ecasound2.2/wily

« back to all changes in this revision

Viewing changes to readline-4.0/display.c

  • Committer: Bazaar Package Importer
  • Author(s): Junichi Uekawa
  • Date: 2008-09-26 09:58:52 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20080926095852-k3v9ewhmxpaltusw
Tags: 2.5.2-3
yodl 2.13.1 removed --unique-output option. Remove --unique-output
accordingly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* display.c -- readline redisplay facility. */
 
2
 
 
3
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
 
4
 
 
5
   This file is part of the GNU Readline Library, a library for
 
6
   reading lines of text with interactive input and history editing.
 
7
 
 
8
   The GNU Readline Library is free software; you can redistribute it
 
9
   and/or modify it under the terms of the GNU General Public License
 
10
   as published by the Free Software Foundation; either version 1, or
 
11
   (at your option) any later version.
 
12
 
 
13
   The GNU Readline Library is distributed in the hope that it will be
 
14
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 
15
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
 
 
18
   The GNU General Public License is often shipped with GNU software, and
 
19
   is generally kept in a file called COPYING or LICENSE.  If you do not
 
20
   have a copy of the license, write to the Free Software Foundation,
 
21
   675 Mass Ave, Cambridge, MA 02139, USA. */
 
22
#define READLINE_LIBRARY
 
23
 
 
24
#if defined (HAVE_CONFIG_H)
 
25
#  include <config.h>
 
26
#endif
 
27
 
 
28
#include <sys/types.h>
 
29
 
 
30
#if defined (HAVE_UNISTD_H)
 
31
#  include <unistd.h>
 
32
#endif /* HAVE_UNISTD_H */
 
33
 
 
34
#include "posixstat.h"
 
35
 
 
36
#if defined (HAVE_STDLIB_H)
 
37
#  include <stdlib.h>
 
38
#else
 
39
#  include "ansi_stdlib.h"
 
40
#endif /* HAVE_STDLIB_H */
 
41
 
 
42
#include <stdio.h>
 
43
 
 
44
#if defined (__GO32__)
 
45
#  include <go32.h>
 
46
#  include <pc.h>
 
47
#endif /* __GO32__ */
 
48
 
 
49
/* System-specific feature definitions and include files. */
 
50
#include "rldefs.h"
 
51
 
 
52
/* Termcap library stuff. */
 
53
#include "tcap.h"
 
54
 
 
55
/* Some standard library routines. */
 
56
#include "readline.h"
 
57
#include "history.h"
 
58
 
 
59
#if !defined (strchr) && !defined (__STDC__)
 
60
extern char *strchr (), *strrchr ();
 
61
#endif /* !strchr && !__STDC__ */
 
62
 
 
63
/* Global and pseudo-global variables and functions
 
64
   imported from readline.c. */
 
65
extern char *rl_prompt;
 
66
extern int readline_echoing_p;
 
67
 
 
68
extern int _rl_output_meta_chars;
 
69
extern int _rl_horizontal_scroll_mode;
 
70
extern int _rl_mark_modified_lines;
 
71
extern int _rl_prefer_visible_bell;
 
72
 
 
73
/* Variables and functions imported from terminal.c */
 
74
extern void _rl_output_some_chars ();
 
75
#ifdef _MINIX
 
76
extern void _rl_output_character_function ();
 
77
#else
 
78
extern int _rl_output_character_function ();
 
79
#endif
 
80
extern int _rl_backspace ();
 
81
 
 
82
extern char *term_clreol, *term_clrpag;
 
83
extern char *term_im, *term_ic,  *term_ei, *term_DC;
 
84
extern char *term_up, *term_dc, *term_cr, *term_IC;
 
85
extern int screenheight, screenwidth, screenchars;
 
86
extern int terminal_can_insert, _rl_term_autowrap;
 
87
 
 
88
/* Pseudo-global functions (local to the readline library) exported
 
89
   by this file. */
 
90
void _rl_move_cursor_relative (), _rl_output_some_chars ();
 
91
void _rl_move_vert ();
 
92
void _rl_clear_to_eol (), _rl_clear_screen ();
 
93
 
 
94
static void update_line (), space_to_eol ();
 
95
static void delete_chars (), insert_some_chars ();
 
96
static void cr ();
 
97
 
 
98
static int *inv_lbreaks, *vis_lbreaks;
 
99
 
 
100
extern char *xmalloc (), *xrealloc ();
 
101
 
 
102
/* Heuristic used to decide whether it is faster to move from CUR to NEW
 
103
   by backing up or outputting a carriage return and moving forward. */
 
104
#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
 
105
 
 
106
/* **************************************************************** */
 
107
/*                                                                  */
 
108
/*                      Display stuff                               */
 
109
/*                                                                  */
 
110
/* **************************************************************** */
 
111
 
 
112
/* This is the stuff that is hard for me.  I never seem to write good
 
113
   display routines in C.  Let's see how I do this time. */
 
114
 
 
115
/* (PWP) Well... Good for a simple line updater, but totally ignores
 
116
   the problems of input lines longer than the screen width.
 
117
 
 
118
   update_line and the code that calls it makes a multiple line,
 
119
   automatically wrapping line update.  Careful attention needs
 
120
   to be paid to the vertical position variables. */
 
121
 
 
122
/* Keep two buffers; one which reflects the current contents of the
 
123
   screen, and the other to draw what we think the new contents should
 
124
   be.  Then compare the buffers, and make whatever changes to the
 
125
   screen itself that we should.  Finally, make the buffer that we
 
126
   just drew into be the one which reflects the current contents of the
 
127
   screen, and place the cursor where it belongs.
 
128
 
 
129
   Commands that want to can fix the display themselves, and then let
 
130
   this function know that the display has been fixed by setting the
 
131
   RL_DISPLAY_FIXED variable.  This is good for efficiency. */
 
132
 
 
133
/* Application-specific redisplay function. */
 
134
VFunction *rl_redisplay_function = rl_redisplay;
 
135
 
 
136
/* Global variables declared here. */
 
137
/* What YOU turn on when you have handled all redisplay yourself. */
 
138
int rl_display_fixed = 0;
 
139
 
 
140
int _rl_suppress_redisplay = 0;
 
141
 
 
142
/* The stuff that gets printed out before the actual text of the line.
 
143
   This is usually pointing to rl_prompt. */
 
144
char *rl_display_prompt = (char *)NULL;
 
145
 
 
146
/* Pseudo-global variables declared here. */
 
147
/* The visible cursor position.  If you print some text, adjust this. */
 
148
int _rl_last_c_pos = 0;
 
149
int _rl_last_v_pos = 0;
 
150
 
 
151
/* Number of lines currently on screen minus 1. */
 
152
int _rl_vis_botlin = 0;
 
153
 
 
154
/* Variables used only in this file. */
 
155
/* The last left edge of text that was displayed.  This is used when
 
156
   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
 
157
static int last_lmargin;
 
158
 
 
159
/* The line display buffers.  One is the line currently displayed on
 
160
   the screen.  The other is the line about to be displayed. */
 
161
static char *visible_line = (char *)NULL;
 
162
static char *invisible_line = (char *)NULL;
 
163
 
 
164
/* A buffer for `modeline' messages. */
 
165
static char msg_buf[128];
 
166
 
 
167
/* Non-zero forces the redisplay even if we thought it was unnecessary. */
 
168
static int forced_display;
 
169
 
 
170
/* Default and initial buffer size.  Can grow. */
 
171
static int line_size = 1024;
 
172
 
 
173
static char *local_prompt, *local_prompt_prefix;
 
174
static int visible_length, prefix_length;
 
175
 
 
176
/* The number of invisible characters in the line currently being
 
177
   displayed on the screen. */
 
178
static int visible_wrap_offset;
 
179
 
 
180
/* static so it can be shared between rl_redisplay and update_line */
 
181
static int wrap_offset;
 
182
 
 
183
/* The index of the last invisible_character in the prompt string. */
 
184
static int last_invisible;
 
185
 
 
186
/* The length (buffer offset) of the first line of the last (possibly
 
187
   multi-line) buffer displayed on the screen. */
 
188
static int visible_first_line_len;
 
189
 
 
190
/* Expand the prompt string S and return the number of visible
 
191
   characters in *LP, if LP is not null.  This is currently more-or-less
 
192
   a placeholder for expansion.  LIP, if non-null is a place to store the
 
193
   index of the last invisible character in ther eturned string. */
 
194
 
 
195
/* Current implementation:
 
196
        \001 (^A) start non-visible characters
 
197
        \002 (^B) end non-visible characters
 
198
   all characters except \001 and \002 (following a \001) are copied to
 
199
   the returned string; all characters except those between \001 and
 
200
   \002 are assumed to be `visible'. */ 
 
201
 
 
202
static char *
 
203
expand_prompt (pmt, lp, lip)
 
204
     char *pmt;
 
205
     int *lp, *lip;
 
206
{
 
207
  char *r, *ret, *p;
 
208
  int l, rl, last, ignoring;
 
209
 
 
210
  /* Short-circuit if we can. */
 
211
  if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
 
212
    {
 
213
      r = savestring (pmt);
 
214
      if (lp)
 
215
        *lp = strlen (r);
 
216
      return r;
 
217
    }
 
218
 
 
219
  l = strlen (pmt);
 
220
  r = ret = xmalloc (l + 1);
 
221
  
 
222
  for (rl = ignoring = last = 0, p = pmt; p && *p; p++)
 
223
    {
 
224
      /* This code strips the invisible character string markers
 
225
         RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
 
226
      if (*p == RL_PROMPT_START_IGNORE)
 
227
        {
 
228
          ignoring++;
 
229
          continue;
 
230
        }
 
231
      else if (ignoring && *p == RL_PROMPT_END_IGNORE)
 
232
        {
 
233
          ignoring = 0;
 
234
          last = r - ret - 1;
 
235
          continue;
 
236
        }
 
237
      else
 
238
        {
 
239
          *r++ = *p;
 
240
          if (!ignoring)
 
241
            rl++;
 
242
        }
 
243
    }
 
244
 
 
245
  *r = '\0';
 
246
  if (lp)
 
247
    *lp = rl;
 
248
  if (lip)
 
249
    *lip = last;
 
250
  return ret;
 
251
}
 
252
 
 
253
/*
 
254
 * Expand the prompt string into the various display components, if
 
255
 * necessary.
 
256
 *
 
257
 * local_prompt = expanded last line of string in rl_display_prompt
 
258
 *                (portion after the final newline)
 
259
 * local_prompt_prefix = portion before last newline of rl_display_prompt,
 
260
 *                       expanded via expand_prompt
 
261
 * visible_length = number of visible characters in local_prompt
 
262
 * prefix_length = number of visible characters in local_prompt_prefix
 
263
 *
 
264
 * This function is called once per call to readline().  It may also be
 
265
 * called arbitrarily to expand the primary prompt.
 
266
 *
 
267
 * The return value is the number of visible characters on the last line
 
268
 * of the (possibly multi-line) prompt.
 
269
 */
 
270
int
 
271
rl_expand_prompt (prompt)
 
272
     char *prompt;
 
273
{
 
274
  char *p, *t;
 
275
  int c;
 
276
 
 
277
  /* Clear out any saved values. */
 
278
  if (local_prompt)
 
279
    free (local_prompt);
 
280
  if (local_prompt_prefix)
 
281
    free (local_prompt_prefix);
 
282
  local_prompt = local_prompt_prefix = (char *)0;
 
283
  last_invisible = visible_length = 0;
 
284
 
 
285
  if (prompt == 0 || *prompt == 0)
 
286
    return (0);
 
287
 
 
288
  p = strrchr (prompt, '\n');
 
289
  if (!p)
 
290
    {
 
291
      /* The prompt is only one line. */
 
292
      local_prompt = expand_prompt (prompt, &visible_length, &last_invisible);
 
293
      local_prompt_prefix = (char *)0;
 
294
      return (visible_length);
 
295
    }
 
296
  else
 
297
    {
 
298
      /* The prompt spans multiple lines. */
 
299
      t = ++p;
 
300
      local_prompt = expand_prompt (p, &visible_length, &last_invisible);
 
301
      c = *t; *t = '\0';
 
302
      /* The portion of the prompt string up to and including the
 
303
         final newline is now null-terminated. */
 
304
      local_prompt_prefix = expand_prompt (prompt, &prefix_length, (int *)NULL);
 
305
      *t = c;
 
306
      return (prefix_length);
 
307
    }
 
308
}
 
309
 
 
310
/* Basic redisplay algorithm. */
 
311
void
 
312
rl_redisplay ()
 
313
{
 
314
  register int in, out, c, linenum, cursor_linenum;
 
315
  register char *line;
 
316
  int c_pos, inv_botlin, lb_botlin, lb_linenum;
 
317
  int newlines, lpos, temp;
 
318
  char *prompt_this_line;
 
319
 
 
320
  if (!readline_echoing_p)
 
321
    return;
 
322
 
 
323
  if (!rl_display_prompt)
 
324
    rl_display_prompt = "";
 
325
 
 
326
  if (invisible_line == 0)
 
327
    {
 
328
      visible_line = xmalloc (line_size);
 
329
      invisible_line = xmalloc (line_size);
 
330
      for (in = 0; in < line_size; in++)
 
331
        {
 
332
          visible_line[in] = 0;
 
333
          invisible_line[in] = 1;
 
334
        }
 
335
 
 
336
      /* should be enough, but then again, this is just for testing. */
 
337
      inv_lbreaks = (int *)malloc (256 * sizeof (int));
 
338
      vis_lbreaks = (int *)malloc (256 * sizeof (int));
 
339
      inv_lbreaks[0] = vis_lbreaks[0] = 0;
 
340
 
 
341
      rl_on_new_line ();
 
342
    }
 
343
 
 
344
  /* Draw the line into the buffer. */
 
345
  c_pos = -1;
 
346
 
 
347
  line = invisible_line;
 
348
  out = inv_botlin = 0;
 
349
 
 
350
  /* Mark the line as modified or not.  We only do this for history
 
351
     lines. */
 
352
  if (_rl_mark_modified_lines && current_history () && rl_undo_list)
 
353
    {
 
354
      line[out++] = '*';
 
355
      line[out] = '\0';
 
356
    }
 
357
 
 
358
  /* If someone thought that the redisplay was handled, but the currently
 
359
     visible line has a different modification state than the one about
 
360
     to become visible, then correct the caller's misconception. */
 
361
  if (visible_line[0] != invisible_line[0])
 
362
    rl_display_fixed = 0;
 
363
 
 
364
  /* If the prompt to be displayed is the `primary' readline prompt (the
 
365
     one passed to readline()), use the values we have already expanded.
 
366
     If not, use what's already in rl_display_prompt.  WRAP_OFFSET is the
 
367
     number of non-visible characters in the prompt string. */
 
368
  if (rl_display_prompt == rl_prompt || local_prompt)
 
369
    {
 
370
      int local_len = local_prompt ? strlen (local_prompt) : 0;
 
371
      if (local_prompt_prefix && forced_display)
 
372
        _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
 
373
 
 
374
      if (local_len > 0)
 
375
        {
 
376
          temp = local_len + out + 2;
 
377
          if (temp >= line_size)
 
378
            {
 
379
              line_size = (temp + 1024) - (temp % 1024);
 
380
              visible_line = xrealloc (visible_line, line_size);
 
381
              line = invisible_line = xrealloc (invisible_line, line_size);
 
382
            }
 
383
          strncpy (line + out, local_prompt, local_len);
 
384
          out += local_len;
 
385
        }
 
386
      line[out] = '\0';
 
387
      wrap_offset = local_len - visible_length;
 
388
    }
 
389
  else
 
390
    {
 
391
      int pmtlen;
 
392
      prompt_this_line = strrchr (rl_display_prompt, '\n');
 
393
      if (!prompt_this_line)
 
394
        prompt_this_line = rl_display_prompt;
 
395
      else
 
396
        {
 
397
          prompt_this_line++;
 
398
          if (forced_display)
 
399
            {
 
400
              _rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);
 
401
              /* Make sure we are at column zero even after a newline,
 
402
                 regardless of the state of terminal output processing. */
 
403
              if (prompt_this_line[-2] != '\r')
 
404
                cr ();
 
405
            }
 
406
        }
 
407
 
 
408
      pmtlen = strlen (prompt_this_line);
 
409
      temp = pmtlen + out + 2;
 
410
      if (temp >= line_size)
 
411
        {
 
412
          line_size = (temp + 1024) - (temp % 1024);
 
413
          visible_line = xrealloc (visible_line, line_size);
 
414
          line = invisible_line = xrealloc (invisible_line, line_size);
 
415
        }
 
416
      strncpy (line + out,  prompt_this_line, pmtlen);
 
417
      out += pmtlen;
 
418
      line[out] = '\0';
 
419
      wrap_offset = 0;
 
420
    }
 
421
 
 
422
#define CHECK_LPOS() \
 
423
      do { \
 
424
        lpos++; \
 
425
        if (lpos >= screenwidth) \
 
426
          { \
 
427
            inv_lbreaks[++newlines] = out; \
 
428
            lpos = 0; \
 
429
          } \
 
430
      } while (0)
 
431
 
 
432
  /* inv_lbreaks[i] is where line i starts in the buffer. */
 
433
  inv_lbreaks[newlines = 0] = 0;
 
434
  lpos = out - wrap_offset;
 
435
 
 
436
  /* XXX - what if lpos is already >= screenwidth before we start drawing the
 
437
     contents of the command line? */
 
438
  while (lpos >= screenwidth)
 
439
    {
 
440
#if 0
 
441
      temp = ((newlines + 1) * screenwidth) - ((newlines == 0) ? wrap_offset : 0);
 
442
#else
 
443
      /* XXX - possible fix from Darin Johnson <darin@acuson.com> for prompt
 
444
         string with invisible characters that is longer than the screen
 
445
         width. */
 
446
      temp = ((newlines + 1) * screenwidth) + ((newlines == 0) ? wrap_offset : 0);
 
447
#endif
 
448
      inv_lbreaks[++newlines] = temp;
 
449
      lpos -= screenwidth;
 
450
    }
 
451
 
 
452
  lb_linenum = 0;
 
453
  for (in = 0; in < rl_end; in++)
 
454
    {
 
455
      c = (unsigned char)rl_line_buffer[in];
 
456
 
 
457
      if (out + 8 >= line_size)         /* XXX - 8 for \t */
 
458
        {
 
459
          line_size *= 2;
 
460
          visible_line = xrealloc (visible_line, line_size);
 
461
          invisible_line = xrealloc (invisible_line, line_size);
 
462
          line = invisible_line;
 
463
        }
 
464
 
 
465
      if (in == rl_point)
 
466
        {
 
467
          c_pos = out;
 
468
          lb_linenum = newlines;
 
469
        }
 
470
 
 
471
      if (META_CHAR (c))
 
472
        {
 
473
          if (_rl_output_meta_chars == 0)
 
474
            {
 
475
              sprintf (line + out, "\\%o", c);
 
476
 
 
477
              if (lpos + 4 >= screenwidth)
 
478
                {
 
479
                  temp = screenwidth - lpos;
 
480
                  inv_lbreaks[++newlines] = out + temp;
 
481
                  lpos = 4 - temp;
 
482
                }
 
483
              else
 
484
                lpos += 4;
 
485
 
 
486
              out += 4;
 
487
            }
 
488
          else
 
489
            {
 
490
              line[out++] = c;
 
491
              CHECK_LPOS();
 
492
            }
 
493
        }
 
494
#if defined (DISPLAY_TABS)
 
495
      else if (c == '\t')
 
496
        {
 
497
          register int temp, newout;
 
498
 
 
499
#if 0
 
500
          newout = (out | (int)7) + 1;
 
501
#else
 
502
          newout = out + 8 - lpos % 8;
 
503
#endif
 
504
          temp = newout - out;
 
505
          if (lpos + temp >= screenwidth)
 
506
            {
 
507
              register int temp2;
 
508
              temp2 = screenwidth - lpos;
 
509
              inv_lbreaks[++newlines] = out + temp2;
 
510
              lpos = temp - temp2;
 
511
              while (out < newout)
 
512
                line[out++] = ' ';
 
513
            }
 
514
          else
 
515
            {
 
516
              while (out < newout)
 
517
                line[out++] = ' ';
 
518
              lpos += temp;
 
519
            }
 
520
        }
 
521
#endif
 
522
      else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && term_up && *term_up)
 
523
        {
 
524
          line[out++] = '\0';   /* XXX - sentinel */
 
525
          inv_lbreaks[++newlines] = out;
 
526
          lpos = 0;
 
527
        }
 
528
      else if (CTRL_CHAR (c) || c == RUBOUT)
 
529
        {
 
530
          line[out++] = '^';
 
531
          CHECK_LPOS();
 
532
          line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
 
533
          CHECK_LPOS();
 
534
        }
 
535
      else
 
536
        {
 
537
          line[out++] = c;
 
538
          CHECK_LPOS();
 
539
        }
 
540
    }
 
541
  line[out] = '\0';
 
542
  if (c_pos < 0)
 
543
    {
 
544
      c_pos = out;
 
545
      lb_linenum = newlines;
 
546
    }
 
547
 
 
548
  inv_botlin = lb_botlin = newlines;
 
549
  inv_lbreaks[newlines+1] = out;
 
550
  cursor_linenum = lb_linenum;
 
551
 
 
552
  /* C_POS == position in buffer where cursor should be placed. */
 
553
 
 
554
  /* PWP: now is when things get a bit hairy.  The visible and invisible
 
555
     line buffers are really multiple lines, which would wrap every
 
556
     (screenwidth - 1) characters.  Go through each in turn, finding
 
557
     the changed region and updating it.  The line order is top to bottom. */
 
558
 
 
559
  /* If we can move the cursor up and down, then use multiple lines,
 
560
     otherwise, let long lines display in a single terminal line, and
 
561
     horizontally scroll it. */
 
562
 
 
563
  if (_rl_horizontal_scroll_mode == 0 && term_up && *term_up)
 
564
    {
 
565
      int nleft, pos, changed_screen_line;
 
566
 
 
567
      if (!rl_display_fixed || forced_display)
 
568
        {
 
569
          forced_display = 0;
 
570
 
 
571
          /* If we have more than a screenful of material to display, then
 
572
             only display a screenful.  We should display the last screen,
 
573
             not the first.  */
 
574
          if (out >= screenchars)
 
575
            out = screenchars - 1;
 
576
 
 
577
          /* The first line is at character position 0 in the buffer.  The
 
578
             second and subsequent lines start at inv_lbreaks[N], offset by
 
579
             OFFSET (which has already been calculated above).  */
 
580
 
 
581
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
 
582
#define VIS_LLEN(l)     ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
 
583
#define INV_LLEN(l)     (inv_lbreaks[l+1] - inv_lbreaks[l])
 
584
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
 
585
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
 
586
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
 
587
 
 
588
          /* For each line in the buffer, do the updating display. */
 
589
          for (linenum = 0; linenum <= inv_botlin; linenum++)
 
590
            {
 
591
              update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
 
592
                           VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
 
593
 
 
594
              /* If this is the line with the prompt, we might need to
 
595
                 compensate for invisible characters in the new line. Do
 
596
                 this only if there is not more than one new line (which
 
597
                 implies that we completely overwrite the old visible line)
 
598
                 and the new line is shorter than the old.  Make sure we are
 
599
                 at the end of the new line before clearing. */
 
600
              if (linenum == 0 &&
 
601
                  inv_botlin == 0 && _rl_last_c_pos == out &&
 
602
                  (wrap_offset > visible_wrap_offset) &&
 
603
                  (_rl_last_c_pos < visible_first_line_len))
 
604
                {
 
605
                  nleft = screenwidth + wrap_offset - _rl_last_c_pos;
 
606
                  if (nleft)
 
607
                    _rl_clear_to_eol (nleft);
 
608
                }
 
609
 
 
610
              /* Since the new first line is now visible, save its length. */
 
611
              if (linenum == 0)
 
612
                visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
 
613
            }
 
614
 
 
615
          /* We may have deleted some lines.  If so, clear the left over
 
616
             blank ones at the bottom out. */
 
617
          if (_rl_vis_botlin > inv_botlin)
 
618
            {
 
619
              char *tt;
 
620
              for (; linenum <= _rl_vis_botlin; linenum++)
 
621
                {
 
622
                  tt = VIS_CHARS (linenum);
 
623
                  _rl_move_vert (linenum);
 
624
                  _rl_move_cursor_relative (0, tt);
 
625
                  _rl_clear_to_eol
 
626
                    ((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
 
627
                }
 
628
            }
 
629
          _rl_vis_botlin = inv_botlin;
 
630
 
 
631
          /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
 
632
             different screen line during this redisplay. */
 
633
          changed_screen_line = _rl_last_v_pos != cursor_linenum;
 
634
          if (changed_screen_line)
 
635
            {
 
636
              _rl_move_vert (cursor_linenum);
 
637
              /* If we moved up to the line with the prompt using term_up,
 
638
                 the physical cursor position on the screen stays the same,
 
639
                 but the buffer position needs to be adjusted to account
 
640
                 for invisible characters. */
 
641
              if (cursor_linenum == 0 && wrap_offset)
 
642
                _rl_last_c_pos += wrap_offset;
 
643
            }
 
644
 
 
645
          /* We have to reprint the prompt if it contains invisible
 
646
             characters, since it's not generally OK to just reprint
 
647
             the characters from the current cursor position.  But we
 
648
             only need to reprint it if the cursor is before the last
 
649
             invisible character in the prompt string. */
 
650
          nleft = visible_length + wrap_offset;
 
651
          if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
 
652
              _rl_last_c_pos <= last_invisible && local_prompt)
 
653
            {
 
654
              if (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
 
797
old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
 
798
new:    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 */
 
807
static void
 
808
update_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. */
 
1018
int
 
1019
rl_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. */
 
1033
int
 
1034
rl_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. */
 
1052
void
 
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. */
 
1108
void
 
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. */
 
1145
int
 
1146
rl_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
 
 
1173
int
 
1174
rl_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)
 
1203
int
 
1204
#if defined (PREFER_STDARG)
 
1205
rl_message (const char *format, ...)
 
1206
#else
 
1207
rl_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 */
 
1231
int
 
1232
rl_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". */
 
1243
int
 
1244
rl_clear_message ()
 
1245
{
 
1246
  rl_display_prompt = rl_prompt;
 
1247
  (*rl_redisplay_function) ();
 
1248
  return 0;
 
1249
}
 
1250
 
 
1251
int
 
1252
rl_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
 
 
1261
static char *saved_local_prompt;
 
1262
static char *saved_local_prefix;
 
1263
static int saved_last_invisible;
 
1264
static int saved_visible_length;
 
1265
 
 
1266
void
 
1267
rl_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
 
 
1278
void
 
1279
rl_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
 
 
1292
char *
 
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. */
 
1326
void
 
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, */
 
1343
void
 
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, */
 
1357
static void
 
1358
space_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
 
 
1369
void
 
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. */
 
1381
static void
 
1382
insert_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. */
 
1436
static void
 
1437
delete_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
 
 
1470
void
 
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. */
 
1501
static void
 
1502
cr ()
 
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. */
 
1512
void
 
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
 
 
1554
void
 
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
 
 
1566
void
 
1567
_rl_erase_entire_line ()
 
1568
{
 
1569
  cr ();
 
1570
  _rl_clear_to_eol (0);
 
1571
  cr ();
 
1572
  fflush (rl_outstream);
 
1573
}