* config/cygwin.cache: Prime mbstate_t.
[deliverable/binutils-gdb.git] / readline / display.c
CommitLineData
d60d9f65
SS
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
1b17e766 10 as published by the Free Software Foundation; either version 2, or
d60d9f65
SS
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,
1b17e766 21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
d60d9f65
SS
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
30083a32
EZ
44#ifdef __MSDOS__
45# include <pc.h>
46#endif
47
d60d9f65
SS
48/* System-specific feature definitions and include files. */
49#include "rldefs.h"
9255ee31 50#include "rlmbutil.h"
d60d9f65
SS
51
52/* Termcap library stuff. */
53#include "tcap.h"
54
55/* Some standard library routines. */
56#include "readline.h"
57#include "history.h"
58
1b17e766
EZ
59#include "rlprivate.h"
60#include "xmalloc.h"
61
d60d9f65
SS
62#if !defined (strchr) && !defined (__STDC__)
63extern char *strchr (), *strrchr ();
64#endif /* !strchr && !__STDC__ */
65
1b17e766 66#if defined (HACK_TERMCAP_MOTION)
9255ee31 67extern char *_rl_term_forward_char;
d60d9f65 68#endif
d60d9f65 69
9255ee31
EZ
70static void update_line PARAMS((char *, char *, int, int, int, int));
71static void space_to_eol PARAMS((int));
72static void delete_chars PARAMS((int));
73static void insert_some_chars PARAMS((char *, int, int));
74static void cr PARAMS((void));
75
76#if defined (HANDLE_MULTIBYTE)
77static int _rl_col_width PARAMS((char *, int, int));
78static int *_rl_wrapped_line;
79#else
80# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
81#endif
d60d9f65
SS
82
83static int *inv_lbreaks, *vis_lbreaks;
1b17e766 84static int inv_lbsize, vis_lbsize;
d60d9f65
SS
85
86/* Heuristic used to decide whether it is faster to move from CUR to NEW
87 by backing up or outputting a carriage return and moving forward. */
88#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
89
90/* **************************************************************** */
91/* */
92/* Display stuff */
93/* */
94/* **************************************************************** */
95
96/* This is the stuff that is hard for me. I never seem to write good
97 display routines in C. Let's see how I do this time. */
98
99/* (PWP) Well... Good for a simple line updater, but totally ignores
100 the problems of input lines longer than the screen width.
101
102 update_line and the code that calls it makes a multiple line,
103 automatically wrapping line update. Careful attention needs
104 to be paid to the vertical position variables. */
105
106/* Keep two buffers; one which reflects the current contents of the
107 screen, and the other to draw what we think the new contents should
108 be. Then compare the buffers, and make whatever changes to the
109 screen itself that we should. Finally, make the buffer that we
110 just drew into be the one which reflects the current contents of the
111 screen, and place the cursor where it belongs.
112
113 Commands that want to can fix the display themselves, and then let
114 this function know that the display has been fixed by setting the
115 RL_DISPLAY_FIXED variable. This is good for efficiency. */
116
117/* Application-specific redisplay function. */
9255ee31 118rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
d60d9f65
SS
119
120/* Global variables declared here. */
121/* What YOU turn on when you have handled all redisplay yourself. */
122int rl_display_fixed = 0;
123
124int _rl_suppress_redisplay = 0;
125
126/* The stuff that gets printed out before the actual text of the line.
127 This is usually pointing to rl_prompt. */
128char *rl_display_prompt = (char *)NULL;
129
130/* Pseudo-global variables declared here. */
131/* The visible cursor position. If you print some text, adjust this. */
132int _rl_last_c_pos = 0;
133int _rl_last_v_pos = 0;
134
135/* Number of lines currently on screen minus 1. */
136int _rl_vis_botlin = 0;
137
138/* Variables used only in this file. */
139/* The last left edge of text that was displayed. This is used when
140 doing horizontal scrolling. It shifts in thirds of a screenwidth. */
141static int last_lmargin;
142
143/* The line display buffers. One is the line currently displayed on
144 the screen. The other is the line about to be displayed. */
145static char *visible_line = (char *)NULL;
146static char *invisible_line = (char *)NULL;
147
148/* A buffer for `modeline' messages. */
149static char msg_buf[128];
150
151/* Non-zero forces the redisplay even if we thought it was unnecessary. */
152static int forced_display;
153
154/* Default and initial buffer size. Can grow. */
155static int line_size = 1024;
156
9255ee31
EZ
157/* Variables to keep track of the expanded prompt string, which may
158 include invisible characters. */
159
d60d9f65 160static char *local_prompt, *local_prompt_prefix;
9255ee31 161static int prompt_visible_length, prompt_prefix_length;
d60d9f65
SS
162
163/* The number of invisible characters in the line currently being
164 displayed on the screen. */
165static int visible_wrap_offset;
166
9255ee31
EZ
167/* The number of invisible characters in the prompt string. Static so it
168 can be shared between rl_redisplay and update_line */
d60d9f65
SS
169static int wrap_offset;
170
9255ee31
EZ
171/* The index of the last invisible character in the prompt string. */
172static int prompt_last_invisible;
d60d9f65
SS
173
174/* The length (buffer offset) of the first line of the last (possibly
175 multi-line) buffer displayed on the screen. */
176static int visible_first_line_len;
177
9255ee31
EZ
178/* Number of invisible characters on the first physical line of the prompt.
179 Only valid when the number of physical characters in the prompt exceeds
180 (or is equal to) _rl_screenwidth. */
181static int prompt_invis_chars_first_line;
182
183static int prompt_last_screen_line;
184
d60d9f65
SS
185/* Expand the prompt string S and return the number of visible
186 characters in *LP, if LP is not null. This is currently more-or-less
187 a placeholder for expansion. LIP, if non-null is a place to store the
9255ee31
EZ
188 index of the last invisible character in the returned string. NIFLP,
189 if non-zero, is a place to store the number of invisible characters in
190 the first prompt line. */
d60d9f65
SS
191
192/* Current implementation:
193 \001 (^A) start non-visible characters
194 \002 (^B) end non-visible characters
195 all characters except \001 and \002 (following a \001) are copied to
196 the returned string; all characters except those between \001 and
197 \002 are assumed to be `visible'. */
198
199static char *
9255ee31 200expand_prompt (pmt, lp, lip, niflp)
d60d9f65 201 char *pmt;
9255ee31 202 int *lp, *lip, *niflp;
d60d9f65
SS
203{
204 char *r, *ret, *p;
9255ee31 205 int l, rl, last, ignoring, ninvis, invfl;
d60d9f65
SS
206
207 /* Short-circuit if we can. */
208 if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
209 {
210 r = savestring (pmt);
211 if (lp)
212 *lp = strlen (r);
213 return r;
214 }
215
216 l = strlen (pmt);
9255ee31
EZ
217 r = ret = (char *)xmalloc (l + 1);
218
219 invfl = 0; /* invisible chars in first line of prompt */
220
221 for (rl = ignoring = last = ninvis = 0, p = pmt; p && *p; p++)
d60d9f65
SS
222 {
223 /* This code strips the invisible character string markers
224 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
225 if (*p == RL_PROMPT_START_IGNORE)
226 {
227 ignoring++;
228 continue;
229 }
230 else if (ignoring && *p == RL_PROMPT_END_IGNORE)
231 {
232 ignoring = 0;
233 last = r - ret - 1;
234 continue;
235 }
236 else
237 {
238 *r++ = *p;
239 if (!ignoring)
240 rl++;
9255ee31
EZ
241 else
242 ninvis++;
243 if (rl == _rl_screenwidth)
244 invfl = ninvis;
d60d9f65
SS
245 }
246 }
247
9255ee31
EZ
248 if (rl < _rl_screenwidth)
249 invfl = ninvis;
250
d60d9f65
SS
251 *r = '\0';
252 if (lp)
253 *lp = rl;
254 if (lip)
255 *lip = last;
9255ee31
EZ
256 if (niflp)
257 *niflp = invfl;
d60d9f65
SS
258 return ret;
259}
260
1b17e766
EZ
261/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
262 PMT and return the rest of PMT. */
263char *
264_rl_strip_prompt (pmt)
265 char *pmt;
266{
267 char *ret;
268
9255ee31 269 ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL);
1b17e766
EZ
270 return ret;
271}
272
d60d9f65
SS
273/*
274 * Expand the prompt string into the various display components, if
275 * necessary.
276 *
277 * local_prompt = expanded last line of string in rl_display_prompt
278 * (portion after the final newline)
279 * local_prompt_prefix = portion before last newline of rl_display_prompt,
280 * expanded via expand_prompt
9255ee31
EZ
281 * prompt_visible_length = number of visible characters in local_prompt
282 * prompt_prefix_length = number of visible characters in local_prompt_prefix
d60d9f65
SS
283 *
284 * This function is called once per call to readline(). It may also be
285 * called arbitrarily to expand the primary prompt.
286 *
287 * The return value is the number of visible characters on the last line
288 * of the (possibly multi-line) prompt.
289 */
290int
291rl_expand_prompt (prompt)
292 char *prompt;
293{
294 char *p, *t;
295 int c;
296
297 /* Clear out any saved values. */
9255ee31
EZ
298 FREE (local_prompt);
299 FREE (local_prompt_prefix);
300
d60d9f65 301 local_prompt = local_prompt_prefix = (char *)0;
9255ee31 302 prompt_last_invisible = prompt_visible_length = 0;
d60d9f65
SS
303
304 if (prompt == 0 || *prompt == 0)
305 return (0);
306
307 p = strrchr (prompt, '\n');
308 if (!p)
309 {
9255ee31
EZ
310 /* The prompt is only one logical line, though it might wrap. */
311 local_prompt = expand_prompt (prompt, &prompt_visible_length,
312 &prompt_last_invisible,
313 &prompt_invis_chars_first_line);
d60d9f65 314 local_prompt_prefix = (char *)0;
9255ee31 315 return (prompt_visible_length);
d60d9f65
SS
316 }
317 else
318 {
319 /* The prompt spans multiple lines. */
320 t = ++p;
9255ee31
EZ
321 local_prompt = expand_prompt (p, &prompt_visible_length,
322 &prompt_last_invisible,
323 &prompt_invis_chars_first_line);
d60d9f65
SS
324 c = *t; *t = '\0';
325 /* The portion of the prompt string up to and including the
326 final newline is now null-terminated. */
9255ee31
EZ
327 local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
328 (int *)NULL,
329 &prompt_invis_chars_first_line);
d60d9f65 330 *t = c;
9255ee31 331 return (prompt_prefix_length);
d60d9f65
SS
332 }
333}
334
1b17e766
EZ
335/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
336 arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
337 and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
338 increased. If the lines have already been allocated, this ensures that
339 they can hold at least MINSIZE characters. */
340static void
341init_line_structures (minsize)
342 int minsize;
343{
344 register int n;
345
346 if (invisible_line == 0) /* initialize it */
347 {
348 if (line_size < minsize)
349 line_size = minsize;
9255ee31
EZ
350 visible_line = (char *)xmalloc (line_size);
351 invisible_line = (char *)xmalloc (line_size);
1b17e766
EZ
352 }
353 else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
354 {
355 line_size *= 2;
356 if (line_size < minsize)
357 line_size = minsize;
9255ee31
EZ
358 visible_line = (char *)xrealloc (visible_line, line_size);
359 invisible_line = (char *)xrealloc (invisible_line, line_size);
1b17e766
EZ
360 }
361
362 for (n = minsize; n < line_size; n++)
363 {
364 visible_line[n] = 0;
365 invisible_line[n] = 1;
366 }
367
368 if (vis_lbreaks == 0)
369 {
370 /* should be enough. */
371 inv_lbsize = vis_lbsize = 256;
372 inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
373 vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
9255ee31
EZ
374#if defined (HANDLE_MULTIBYTE)
375 _rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int));
376#endif
1b17e766
EZ
377 inv_lbreaks[0] = vis_lbreaks[0] = 0;
378 }
379}
380
d60d9f65
SS
381/* Basic redisplay algorithm. */
382void
383rl_redisplay ()
384{
385 register int in, out, c, linenum, cursor_linenum;
386 register char *line;
387 int c_pos, inv_botlin, lb_botlin, lb_linenum;
388 int newlines, lpos, temp;
389 char *prompt_this_line;
9255ee31
EZ
390#if defined (HANDLE_MULTIBYTE)
391 wchar_t wc;
392 size_t wc_bytes;
393 int wc_width;
394 mbstate_t ps;
395 int _rl_wrapped_multicolumn = 0;
396#endif
d60d9f65
SS
397
398 if (!readline_echoing_p)
399 return;
400
401 if (!rl_display_prompt)
402 rl_display_prompt = "";
403
404 if (invisible_line == 0)
405 {
1b17e766 406 init_line_structures (0);
d60d9f65
SS
407 rl_on_new_line ();
408 }
409
410 /* Draw the line into the buffer. */
411 c_pos = -1;
412
413 line = invisible_line;
414 out = inv_botlin = 0;
415
416 /* Mark the line as modified or not. We only do this for history
417 lines. */
418 if (_rl_mark_modified_lines && current_history () && rl_undo_list)
419 {
420 line[out++] = '*';
421 line[out] = '\0';
422 }
423
424 /* If someone thought that the redisplay was handled, but the currently
425 visible line has a different modification state than the one about
426 to become visible, then correct the caller's misconception. */
427 if (visible_line[0] != invisible_line[0])
428 rl_display_fixed = 0;
429
430 /* If the prompt to be displayed is the `primary' readline prompt (the
431 one passed to readline()), use the values we have already expanded.
432 If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
433 number of non-visible characters in the prompt string. */
434 if (rl_display_prompt == rl_prompt || local_prompt)
435 {
436 int local_len = local_prompt ? strlen (local_prompt) : 0;
437 if (local_prompt_prefix && forced_display)
438 _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
439
440 if (local_len > 0)
441 {
c862e87b
JM
442 temp = local_len + out + 2;
443 if (temp >= line_size)
444 {
445 line_size = (temp + 1024) - (temp % 1024);
9255ee31
EZ
446 visible_line = (char *)xrealloc (visible_line, line_size);
447 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
c862e87b 448 }
d60d9f65
SS
449 strncpy (line + out, local_prompt, local_len);
450 out += local_len;
451 }
452 line[out] = '\0';
9255ee31 453 wrap_offset = local_len - prompt_visible_length;
d60d9f65
SS
454 }
455 else
456 {
457 int pmtlen;
458 prompt_this_line = strrchr (rl_display_prompt, '\n');
459 if (!prompt_this_line)
460 prompt_this_line = rl_display_prompt;
461 else
462 {
463 prompt_this_line++;
1b17e766 464 pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
d60d9f65
SS
465 if (forced_display)
466 {
1b17e766 467 _rl_output_some_chars (rl_display_prompt, pmtlen);
d60d9f65
SS
468 /* Make sure we are at column zero even after a newline,
469 regardless of the state of terminal output processing. */
1b17e766 470 if (pmtlen < 2 || prompt_this_line[-2] != '\r')
d60d9f65
SS
471 cr ();
472 }
473 }
474
475 pmtlen = strlen (prompt_this_line);
c862e87b
JM
476 temp = pmtlen + out + 2;
477 if (temp >= line_size)
478 {
479 line_size = (temp + 1024) - (temp % 1024);
9255ee31
EZ
480 visible_line = (char *)xrealloc (visible_line, line_size);
481 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
c862e87b 482 }
d60d9f65
SS
483 strncpy (line + out, prompt_this_line, pmtlen);
484 out += pmtlen;
485 line[out] = '\0';
9255ee31 486 wrap_offset = prompt_invis_chars_first_line = 0;
d60d9f65
SS
487 }
488
1b17e766
EZ
489#define CHECK_INV_LBREAKS() \
490 do { \
491 if (newlines >= (inv_lbsize - 2)) \
492 { \
493 inv_lbsize *= 2; \
494 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
495 } \
496 } while (0)
9255ee31
EZ
497
498#if defined (HANDLE_MULTIBYTE)
d60d9f65
SS
499#define CHECK_LPOS() \
500 do { \
c862e87b 501 lpos++; \
9255ee31 502 if (lpos >= _rl_screenwidth) \
c862e87b 503 { \
1b17e766
EZ
504 if (newlines >= (inv_lbsize - 2)) \
505 { \
506 inv_lbsize *= 2; \
507 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
9255ee31 508 _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
1b17e766 509 } \
c862e87b 510 inv_lbreaks[++newlines] = out; \
9255ee31 511 _rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \
c862e87b
JM
512 lpos = 0; \
513 } \
d60d9f65 514 } while (0)
9255ee31
EZ
515#else
516#define CHECK_LPOS() \
517 do { \
518 lpos++; \
519 if (lpos >= _rl_screenwidth) \
520 { \
521 if (newlines >= (inv_lbsize - 2)) \
522 { \
523 inv_lbsize *= 2; \
524 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
525 } \
526 inv_lbreaks[++newlines] = out; \
527 lpos = 0; \
528 } \
529 } while (0)
530#endif
d60d9f65
SS
531
532 /* inv_lbreaks[i] is where line i starts in the buffer. */
533 inv_lbreaks[newlines = 0] = 0;
534 lpos = out - wrap_offset;
9255ee31
EZ
535#if defined (HANDLE_MULTIBYTE)
536 memset (_rl_wrapped_line, 0, vis_lbsize);
537#endif
538
539 /* prompt_invis_chars_first_line is the number of invisible characters in
540 the first physical line of the prompt.
541 wrap_offset - prompt_invis_chars_first_line is the number of invis
542 chars on the second line. */
d60d9f65 543
9255ee31 544 /* what if lpos is already >= _rl_screenwidth before we start drawing the
d60d9f65 545 contents of the command line? */
9255ee31 546 while (lpos >= _rl_screenwidth)
d60d9f65 547 {
9255ee31
EZ
548 /* fix from Darin Johnson <darin@acuson.com> for prompt string with
549 invisible characters that is longer than the screen width. The
550 prompt_invis_chars_first_line variable could be made into an array
551 saying how many invisible characters there are per line, but that's
552 probably too much work for the benefit gained. How many people have
553 prompts that exceed two physical lines? */
554 temp = ((newlines + 1) * _rl_screenwidth) +
555#if 0
556 ((newlines == 0) ? prompt_invis_chars_first_line : 0) +
557#else
558 ((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) +
559#endif
560 ((newlines == 1) ? wrap_offset : 0);
1b17e766 561
d60d9f65 562 inv_lbreaks[++newlines] = temp;
9255ee31 563 lpos -= _rl_screenwidth;
d60d9f65
SS
564 }
565
9255ee31
EZ
566 prompt_last_screen_line = newlines;
567
568 /* Draw the rest of the line (after the prompt) into invisible_line, keeping
569 track of where the cursor is (c_pos), the number of the line containing
570 the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
571 It maintains an array of line breaks for display (inv_lbreaks).
572 This handles expanding tabs for display and displaying meta characters. */
d60d9f65 573 lb_linenum = 0;
9255ee31
EZ
574#if defined (HANDLE_MULTIBYTE)
575 in = 0;
576 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
577 {
578 memset (&ps, 0, sizeof (mbstate_t));
579 wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
580 }
581 else
582 wc_bytes = 1;
583 while (in < rl_end)
584#else
d60d9f65 585 for (in = 0; in < rl_end; in++)
9255ee31 586#endif
d60d9f65
SS
587 {
588 c = (unsigned char)rl_line_buffer[in];
589
9255ee31
EZ
590#if defined (HANDLE_MULTIBYTE)
591 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
592 {
593 if (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2)
594 {
595 /* Byte sequence is invalid or shortened. Assume that the
596 first byte represents a character. */
597 wc_bytes = 1;
598 /* Assume that a character occupies a single column. */
599 wc_width = 1;
600 memset (&ps, 0, sizeof (mbstate_t));
601 }
602 else if (wc_bytes == (size_t)0)
603 break; /* Found '\0' */
604 else
605 {
606 temp = wcwidth (wc);
607 wc_width = (temp < 0) ? 1 : temp;
608 }
609 }
610#endif
611
d60d9f65
SS
612 if (out + 8 >= line_size) /* XXX - 8 for \t */
613 {
614 line_size *= 2;
9255ee31
EZ
615 visible_line = (char *)xrealloc (visible_line, line_size);
616 invisible_line = (char *)xrealloc (invisible_line, line_size);
d60d9f65
SS
617 line = invisible_line;
618 }
619
620 if (in == rl_point)
621 {
622 c_pos = out;
623 lb_linenum = newlines;
624 }
625
9255ee31
EZ
626#if defined (HANDLE_MULTIBYTE)
627 if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
628#else
d60d9f65 629 if (META_CHAR (c))
9255ee31 630#endif
d60d9f65
SS
631 {
632 if (_rl_output_meta_chars == 0)
633 {
634 sprintf (line + out, "\\%o", c);
635
9255ee31 636 if (lpos + 4 >= _rl_screenwidth)
d60d9f65 637 {
9255ee31 638 temp = _rl_screenwidth - lpos;
1b17e766 639 CHECK_INV_LBREAKS ();
d60d9f65
SS
640 inv_lbreaks[++newlines] = out + temp;
641 lpos = 4 - temp;
642 }
643 else
644 lpos += 4;
645
646 out += 4;
647 }
648 else
649 {
650 line[out++] = c;
651 CHECK_LPOS();
652 }
653 }
654#if defined (DISPLAY_TABS)
655 else if (c == '\t')
656 {
9255ee31 657 register int newout;
c862e87b
JM
658
659#if 0
d60d9f65 660 newout = (out | (int)7) + 1;
c862e87b
JM
661#else
662 newout = out + 8 - lpos % 8;
663#endif
d60d9f65 664 temp = newout - out;
9255ee31 665 if (lpos + temp >= _rl_screenwidth)
d60d9f65
SS
666 {
667 register int temp2;
9255ee31 668 temp2 = _rl_screenwidth - lpos;
1b17e766 669 CHECK_INV_LBREAKS ();
d60d9f65
SS
670 inv_lbreaks[++newlines] = out + temp2;
671 lpos = temp - temp2;
672 while (out < newout)
673 line[out++] = ' ';
674 }
675 else
676 {
677 while (out < newout)
678 line[out++] = ' ';
679 lpos += temp;
680 }
681 }
682#endif
9255ee31 683 else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
c862e87b
JM
684 {
685 line[out++] = '\0'; /* XXX - sentinel */
1b17e766 686 CHECK_INV_LBREAKS ();
c862e87b
JM
687 inv_lbreaks[++newlines] = out;
688 lpos = 0;
689 }
d60d9f65
SS
690 else if (CTRL_CHAR (c) || c == RUBOUT)
691 {
692 line[out++] = '^';
693 CHECK_LPOS();
694 line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
695 CHECK_LPOS();
696 }
697 else
698 {
9255ee31
EZ
699#if defined (HANDLE_MULTIBYTE)
700 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
701 {
702 register int i;
703
704 _rl_wrapped_multicolumn = 0;
705
706 if (_rl_screenwidth < lpos + wc_width)
707 for (i = lpos; i < _rl_screenwidth; i++)
708 {
709 /* The space will be removed in update_line() */
710 line[out++] = ' ';
711 _rl_wrapped_multicolumn++;
712 CHECK_LPOS();
713 }
714 if (in == rl_point)
715 {
716 c_pos = out;
717 lb_linenum = newlines;
718 }
719 for (i = in; i < in+wc_bytes; i++)
720 line[out++] = rl_line_buffer[i];
721 for (i = 0; i < wc_width; i++)
722 CHECK_LPOS();
723 }
724 else
725 {
726 line[out++] = c;
727 CHECK_LPOS();
728 }
729#else
d60d9f65
SS
730 line[out++] = c;
731 CHECK_LPOS();
9255ee31 732#endif
d60d9f65 733 }
9255ee31
EZ
734
735#if defined (HANDLE_MULTIBYTE)
736 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
737 {
738 in += wc_bytes;
739 wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
740 }
741 else
742 in++;
743#endif
744
d60d9f65
SS
745 }
746 line[out] = '\0';
747 if (c_pos < 0)
748 {
749 c_pos = out;
750 lb_linenum = newlines;
751 }
752
753 inv_botlin = lb_botlin = newlines;
1b17e766 754 CHECK_INV_LBREAKS ();
d60d9f65
SS
755 inv_lbreaks[newlines+1] = out;
756 cursor_linenum = lb_linenum;
757
9255ee31
EZ
758 /* C_POS == position in buffer where cursor should be placed.
759 CURSOR_LINENUM == line number where the cursor should be placed. */
d60d9f65
SS
760
761 /* PWP: now is when things get a bit hairy. The visible and invisible
762 line buffers are really multiple lines, which would wrap every
763 (screenwidth - 1) characters. Go through each in turn, finding
764 the changed region and updating it. The line order is top to bottom. */
765
766 /* If we can move the cursor up and down, then use multiple lines,
767 otherwise, let long lines display in a single terminal line, and
768 horizontally scroll it. */
769
9255ee31 770 if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
d60d9f65
SS
771 {
772 int nleft, pos, changed_screen_line;
773
774 if (!rl_display_fixed || forced_display)
775 {
776 forced_display = 0;
777
778 /* If we have more than a screenful of material to display, then
779 only display a screenful. We should display the last screen,
780 not the first. */
9255ee31
EZ
781 if (out >= _rl_screenchars)
782 {
783 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
784 out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
785 else
786 out = _rl_screenchars - 1;
787 }
d60d9f65
SS
788
789 /* The first line is at character position 0 in the buffer. The
790 second and subsequent lines start at inv_lbreaks[N], offset by
791 OFFSET (which has already been calculated above). */
792
793#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
794#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
795#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
796#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
797#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
798#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
799
800 /* For each line in the buffer, do the updating display. */
801 for (linenum = 0; linenum <= inv_botlin; linenum++)
802 {
803 update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
804 VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
805
806 /* If this is the line with the prompt, we might need to
807 compensate for invisible characters in the new line. Do
808 this only if there is not more than one new line (which
809 implies that we completely overwrite the old visible line)
810 and the new line is shorter than the old. Make sure we are
811 at the end of the new line before clearing. */
812 if (linenum == 0 &&
813 inv_botlin == 0 && _rl_last_c_pos == out &&
814 (wrap_offset > visible_wrap_offset) &&
815 (_rl_last_c_pos < visible_first_line_len))
816 {
9255ee31 817 nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
d60d9f65
SS
818 if (nleft)
819 _rl_clear_to_eol (nleft);
820 }
821
822 /* Since the new first line is now visible, save its length. */
823 if (linenum == 0)
824 visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
825 }
826
827 /* We may have deleted some lines. If so, clear the left over
828 blank ones at the bottom out. */
829 if (_rl_vis_botlin > inv_botlin)
830 {
831 char *tt;
832 for (; linenum <= _rl_vis_botlin; linenum++)
833 {
834 tt = VIS_CHARS (linenum);
835 _rl_move_vert (linenum);
836 _rl_move_cursor_relative (0, tt);
837 _rl_clear_to_eol
9255ee31 838 ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
d60d9f65
SS
839 }
840 }
841 _rl_vis_botlin = inv_botlin;
842
843 /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
844 different screen line during this redisplay. */
845 changed_screen_line = _rl_last_v_pos != cursor_linenum;
846 if (changed_screen_line)
847 {
848 _rl_move_vert (cursor_linenum);
9255ee31 849 /* If we moved up to the line with the prompt using _rl_term_up,
c862e87b
JM
850 the physical cursor position on the screen stays the same,
851 but the buffer position needs to be adjusted to account
852 for invisible characters. */
d60d9f65 853 if (cursor_linenum == 0 && wrap_offset)
c862e87b 854 _rl_last_c_pos += wrap_offset;
d60d9f65
SS
855 }
856
857 /* We have to reprint the prompt if it contains invisible
858 characters, since it's not generally OK to just reprint
859 the characters from the current cursor position. But we
860 only need to reprint it if the cursor is before the last
861 invisible character in the prompt string. */
9255ee31 862 nleft = prompt_visible_length + wrap_offset;
d60d9f65 863 if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
9255ee31 864 _rl_last_c_pos <= prompt_last_invisible && local_prompt)
d60d9f65 865 {
771578d1
SS
866#if defined (__MSDOS__)
867 putc ('\r', rl_outstream);
868#else
9255ee31
EZ
869 if (_rl_term_cr)
870 tputs (_rl_term_cr, 1, _rl_output_character_function);
771578d1 871#endif
d60d9f65 872 _rl_output_some_chars (local_prompt, nleft);
9255ee31
EZ
873 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
874 _rl_last_c_pos = _rl_col_width(local_prompt, 0, nleft);
875 else
876 _rl_last_c_pos = nleft;
d60d9f65
SS
877 }
878
879 /* Where on that line? And where does that line start
880 in the buffer? */
881 pos = inv_lbreaks[cursor_linenum];
882 /* nleft == number of characters in the line buffer between the
883 start of the line and the cursor position. */
884 nleft = c_pos - pos;
885
886 /* Since _rl_backspace() doesn't know about invisible characters in the
887 prompt, and there's no good way to tell it, we compensate for
888 those characters here and call _rl_backspace() directly. */
889 if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
890 {
891 _rl_backspace (_rl_last_c_pos - nleft);
9255ee31
EZ
892 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
893 _rl_last_c_pos = _rl_col_width (&visible_line[pos], 0, nleft);
894 else
895 _rl_last_c_pos = nleft;
d60d9f65
SS
896 }
897
9255ee31
EZ
898 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
899 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
900 else if (nleft != _rl_last_c_pos)
d60d9f65
SS
901 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
902 }
903 }
904 else /* Do horizontal scrolling. */
905 {
906#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
907 int lmargin, ndisp, nleft, phys_c_pos, t;
908
909 /* Always at top line. */
910 _rl_last_v_pos = 0;
911
912 /* Compute where in the buffer the displayed line should start. This
913 will be LMARGIN. */
914
915 /* The number of characters that will be displayed before the cursor. */
916 ndisp = c_pos - wrap_offset;
9255ee31 917 nleft = prompt_visible_length + wrap_offset;
d60d9f65 918 /* Where the new cursor position will be on the screen. This can be
c862e87b 919 longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
d60d9f65 920 phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
9255ee31 921 t = _rl_screenwidth / 3;
d60d9f65
SS
922
923 /* If the number of characters had already exceeded the screenwidth,
c862e87b 924 last_lmargin will be > 0. */
d60d9f65
SS
925
926 /* If the number of characters to be displayed is more than the screen
c862e87b
JM
927 width, compute the starting offset so that the cursor is about
928 two-thirds of the way across the screen. */
9255ee31 929 if (phys_c_pos > _rl_screenwidth - 2)
d60d9f65
SS
930 {
931 lmargin = c_pos - (2 * t);
932 if (lmargin < 0)
933 lmargin = 0;
934 /* If the left margin would be in the middle of a prompt with
935 invisible characters, don't display the prompt at all. */
936 if (wrap_offset && lmargin > 0 && lmargin < nleft)
937 lmargin = nleft;
938 }
9255ee31 939 else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
c862e87b 940 lmargin = 0;
d60d9f65
SS
941 else if (phys_c_pos < 1)
942 {
943 /* If we are moving back towards the beginning of the line and
944 the last margin is no longer correct, compute a new one. */
945 lmargin = ((c_pos - 1) / t) * t; /* XXX */
946 if (wrap_offset && lmargin > 0 && lmargin < nleft)
947 lmargin = nleft;
948 }
949 else
c862e87b 950 lmargin = last_lmargin;
d60d9f65
SS
951
952 /* If the first character on the screen isn't the first character
953 in the display line, indicate this with a special character. */
954 if (lmargin > 0)
955 line[lmargin] = '<';
956
957 /* If SCREENWIDTH characters starting at LMARGIN do not encompass
c862e87b
JM
958 the whole line, indicate that with a special character at the
959 right edge of the screen. If LMARGIN is 0, we need to take the
960 wrap offset into account. */
9255ee31 961 t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
d60d9f65 962 if (t < out)
c862e87b 963 line[t - 1] = '>';
d60d9f65
SS
964
965 if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
966 {
967 forced_display = 0;
968 update_line (&visible_line[last_lmargin],
969 &invisible_line[lmargin],
970 0,
9255ee31
EZ
971 _rl_screenwidth + visible_wrap_offset,
972 _rl_screenwidth + (lmargin ? 0 : wrap_offset),
d60d9f65
SS
973 0);
974
975 /* If the visible new line is shorter than the old, but the number
976 of invisible characters is greater, and we are at the end of
977 the new line, we need to clear to eol. */
978 t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
979 if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
980 (_rl_last_c_pos == out) &&
981 t < visible_first_line_len)
982 {
9255ee31 983 nleft = _rl_screenwidth - t;
d60d9f65
SS
984 _rl_clear_to_eol (nleft);
985 }
986 visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
9255ee31
EZ
987 if (visible_first_line_len > _rl_screenwidth)
988 visible_first_line_len = _rl_screenwidth;
d60d9f65
SS
989
990 _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
991 last_lmargin = lmargin;
992 }
993 }
994 fflush (rl_outstream);
995
996 /* Swap visible and non-visible lines. */
997 {
9255ee31 998 char *vtemp = visible_line;
1b17e766
EZ
999 int *itemp = vis_lbreaks, ntemp = vis_lbsize;
1000
d60d9f65 1001 visible_line = invisible_line;
9255ee31 1002 invisible_line = vtemp;
1b17e766 1003
d60d9f65
SS
1004 vis_lbreaks = inv_lbreaks;
1005 inv_lbreaks = itemp;
1b17e766
EZ
1006
1007 vis_lbsize = inv_lbsize;
1008 inv_lbsize = ntemp;
1009
d60d9f65
SS
1010 rl_display_fixed = 0;
1011 /* If we are displaying on a single line, and last_lmargin is > 0, we
1012 are not displaying any invisible characters, so set visible_wrap_offset
1013 to 0. */
1014 if (_rl_horizontal_scroll_mode && last_lmargin)
1015 visible_wrap_offset = 0;
1016 else
1017 visible_wrap_offset = wrap_offset;
1018 }
1019}
1020
1021/* PWP: update_line() is based on finding the middle difference of each
1022 line on the screen; vis:
1023
1024 /old first difference
1025 /beginning of line | /old last same /old EOL
1026 v v v v
1027old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
1028new: eddie> Oh, my little buggy says to me, as lurgid as
1029 ^ ^ ^ ^
1030 \beginning of line | \new last same \new end of line
1031 \new first difference
1032
1033 All are character pointers for the sake of speed. Special cases for
c862e87b 1034 no differences, as well as for end of line additions must be handled.
d60d9f65
SS
1035
1036 Could be made even smarter, but this works well enough */
1037static void
1038update_line (old, new, current_line, omax, nmax, inv_botlin)
1039 register char *old, *new;
1040 int current_line, omax, nmax, inv_botlin;
1041{
1042 register char *ofd, *ols, *oe, *nfd, *nls, *ne;
1043 int temp, lendiff, wsatend, od, nd;
1044 int current_invis_chars;
9255ee31
EZ
1045 int col_lendiff, col_temp;
1046#if defined (HANDLE_MULTIBYTE)
1047 mbstate_t ps_new, ps_old;
1048 int new_offset, old_offset, tmp;
1049#endif
d60d9f65
SS
1050
1051 /* If we're at the right edge of a terminal that supports xn, we're
1052 ready to wrap around, so do so. This fixes problems with knowing
1053 the exact cursor position and cut-and-paste with certain terminal
1054 emulators. In this calculation, TEMP is the physical screen
1055 position of the cursor. */
1056 temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
9255ee31
EZ
1057 if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
1058 && _rl_last_v_pos == current_line - 1)
d60d9f65 1059 {
9255ee31
EZ
1060#if defined (HANDLE_MULTIBYTE)
1061 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1062 {
1063 wchar_t wc;
1064 mbstate_t ps;
1065 int tempwidth, bytes;
1066 size_t ret;
1067
1068 /* This fixes only double-column characters, but if the wrapped
1069 character comsumes more than three columns, spaces will be
1070 inserted in the string buffer. */
1071 if (_rl_wrapped_line[current_line] > 0)
1072 _rl_clear_to_eol (_rl_wrapped_line[current_line]);
1073
1074 memset (&ps, 0, sizeof (mbstate_t));
1075 ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
1076 if (ret == (size_t)-1 || ret == (size_t)-2)
1077 {
1078 tempwidth = 1;
1079 ret = 1;
1080 }
1081 else if (ret == 0)
1082 tempwidth = 0;
1083 else
1084 tempwidth = wcwidth (wc);
1085
1086 if (tempwidth > 0)
1087 {
1088 int count;
1089 bytes = ret;
1090 for (count = 0; count < bytes; count++)
1091 putc (new[count], rl_outstream);
1092 _rl_last_c_pos = tempwidth;
1093 _rl_last_v_pos++;
1094 memset (&ps, 0, sizeof (mbstate_t));
1095 ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
1096 if (ret != 0 && bytes != 0)
1097 {
1098 if (ret == (size_t)-1 || ret == (size_t)-2)
1099 memmove (old+bytes, old+1, strlen (old+1));
1100 else
1101 memmove (old+bytes, old+ret, strlen (old+ret));
1102 memcpy (old, new, bytes);
1103 }
1104 }
1105 else
1106 {
1107 putc (' ', rl_outstream);
1108 _rl_last_c_pos = 1;
1109 _rl_last_v_pos++;
1110 if (old[0] && new[0])
1111 old[0] = new[0];
1112 }
1113 }
d60d9f65 1114 else
9255ee31
EZ
1115#endif
1116 {
1117 if (new[0])
1118 putc (new[0], rl_outstream);
1119 else
1120 putc (' ', rl_outstream);
1121 _rl_last_c_pos = 1; /* XXX */
1122 _rl_last_v_pos++;
1123 if (old[0] && new[0])
1124 old[0] = new[0];
1125 }
d60d9f65 1126 }
9255ee31 1127
d60d9f65
SS
1128
1129 /* Find first difference. */
9255ee31
EZ
1130#if defined (HANDLE_MULTIBYTE)
1131 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1132 {
1133 memset (&ps_new, 0, sizeof(mbstate_t));
1134 memset (&ps_old, 0, sizeof(mbstate_t));
1135
1136 new_offset = old_offset = 0;
1137 for (ofd = old, nfd = new;
1138 (ofd - old < omax) && *ofd &&
1139 _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
1140 {
1141 old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
1142 new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
1143 ofd = old + old_offset;
1144 nfd = new + new_offset;
1145 }
1146 }
1147 else
1148#endif
d60d9f65
SS
1149 for (ofd = old, nfd = new;
1150 (ofd - old < omax) && *ofd && (*ofd == *nfd);
1151 ofd++, nfd++)
1152 ;
1153
1154 /* Move to the end of the screen line. ND and OD are used to keep track
1155 of the distance between ne and new and oe and old, respectively, to
1156 move a subtraction out of each loop. */
1157 for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
1158 for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
1159
1160 /* If no difference, continue to next line. */
1161 if (ofd == oe && nfd == ne)
1162 return;
1163
1164 wsatend = 1; /* flag for trailing whitespace */
9255ee31
EZ
1165
1166#if defined (HANDLE_MULTIBYTE)
1167 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1168 {
1169 ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
1170 nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
1171 while ((ols > ofd) && (nls > nfd))
1172 {
1173 memset (&ps_old, 0, sizeof (mbstate_t));
1174 memset (&ps_new, 0, sizeof (mbstate_t));
1175
1176 _rl_adjust_point (old, ols - old, &ps_old);
1177 _rl_adjust_point (new, nls - new, &ps_new);
1178
1179 if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
1180 break;
1181
1182 if (*ols == ' ')
1183 wsatend = 0;
1184
1185 ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
1186 nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
1187 }
1188 }
1189 else
1190 {
1191#endif /* HANDLE_MULTIBYTE */
d60d9f65
SS
1192 ols = oe - 1; /* find last same */
1193 nls = ne - 1;
1194 while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
1195 {
1196 if (*ols != ' ')
1197 wsatend = 0;
1198 ols--;
1199 nls--;
1200 }
9255ee31
EZ
1201#if defined (HANDLE_MULTIBYTE)
1202 }
1203#endif
d60d9f65
SS
1204
1205 if (wsatend)
1206 {
1207 ols = oe;
1208 nls = ne;
1209 }
9255ee31
EZ
1210#if defined (HANDLE_MULTIBYTE)
1211 /* This may not work for stateful encoding, but who cares? To handle
1212 stateful encoding properly, we have to scan each string from the
1213 beginning and compare. */
1214 else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
1215#else
d60d9f65 1216 else if (*ols != *nls)
9255ee31 1217#endif
d60d9f65
SS
1218 {
1219 if (*ols) /* don't step past the NUL */
9255ee31
EZ
1220 {
1221 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1222 ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
1223 else
1224 ols++;
1225 }
d60d9f65 1226 if (*nls)
9255ee31
EZ
1227 {
1228 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1229 nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
1230 else
1231 nls++;
1232 }
d60d9f65
SS
1233 }
1234
1235 /* count of invisible characters in the current invisible line. */
1236 current_invis_chars = W_OFFSET (current_line, wrap_offset);
1237 if (_rl_last_v_pos != current_line)
1238 {
1239 _rl_move_vert (current_line);
1240 if (current_line == 0 && visible_wrap_offset)
1241 _rl_last_c_pos += visible_wrap_offset;
1242 }
1243
1244 /* If this is the first line and there are invisible characters in the
1245 prompt string, and the prompt string has not changed, and the current
1246 cursor position is before the last invisible character in the prompt,
1247 and the index of the character to move to is past the end of the prompt
1248 string, then redraw the entire prompt string. We can only do this
1249 reliably if the terminal supports a `cr' capability.
1250
1251 This is not an efficiency hack -- there is a problem with redrawing
1252 portions of the prompt string if they contain terminal escape
1253 sequences (like drawing the `unbold' sequence without a corresponding
1254 `bold') that manifests itself on certain terminals. */
1255
1256 lendiff = local_prompt ? strlen (local_prompt) : 0;
1257 od = ofd - old; /* index of first difference in visible line */
1258 if (current_line == 0 && !_rl_horizontal_scroll_mode &&
9255ee31
EZ
1259 _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
1260 od >= lendiff && _rl_last_c_pos <= prompt_last_invisible)
d60d9f65 1261 {
771578d1
SS
1262#if defined (__MSDOS__)
1263 putc ('\r', rl_outstream);
1264#else
9255ee31 1265 tputs (_rl_term_cr, 1, _rl_output_character_function);
1b17e766 1266#endif
d60d9f65 1267 _rl_output_some_chars (local_prompt, lendiff);
9255ee31
EZ
1268 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1269 _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff);
1270 else
1271 _rl_last_c_pos = lendiff;
d60d9f65
SS
1272 }
1273
1274 _rl_move_cursor_relative (od, old);
1275
9255ee31
EZ
1276 /* if (len (new) > len (old))
1277 lendiff == difference in buffer
1278 col_lendiff == difference on screen
1279 When not using multibyte characters, these are equal */
d60d9f65 1280 lendiff = (nls - nfd) - (ols - ofd);
9255ee31
EZ
1281 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1282 col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
1283 else
1284 col_lendiff = lendiff;
d60d9f65
SS
1285
1286 /* If we are changing the number of invisible characters in a line, and
1287 the spot of first difference is before the end of the invisible chars,
1288 lendiff needs to be adjusted. */
1289 if (current_line == 0 && !_rl_horizontal_scroll_mode &&
1290 current_invis_chars != visible_wrap_offset)
9255ee31
EZ
1291 {
1292 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1293 {
1294 lendiff += visible_wrap_offset - current_invis_chars;
1295 col_lendiff += visible_wrap_offset - current_invis_chars;
1296 }
1297 else
1298 {
1299 lendiff += visible_wrap_offset - current_invis_chars;
1300 col_lendiff = lendiff;
1301 }
1302 }
d60d9f65
SS
1303
1304 /* Insert (diff (len (old), len (new)) ch. */
1305 temp = ne - nfd;
9255ee31
EZ
1306 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1307 col_temp = _rl_col_width (new, nfd - new, ne - new);
1308 else
1309 col_temp = temp;
1310
1311 if (col_lendiff > 0) /* XXX - was lendiff */
d60d9f65
SS
1312 {
1313 /* Non-zero if we're increasing the number of lines. */
1314 int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
1315 /* Sometimes it is cheaper to print the characters rather than
1316 use the terminal's capabilities. If we're growing the number
1317 of lines, make sure we actually cause the new line to wrap
1318 around on auto-wrapping terminals. */
9255ee31 1319 if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
d60d9f65 1320 {
9255ee31 1321 /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
d60d9f65 1322 _rl_horizontal_scroll_mode == 1, inserting the characters with
9255ee31 1323 _rl_term_IC or _rl_term_ic will screw up the screen because of the
d60d9f65
SS
1324 invisible characters. We need to just draw them. */
1325 if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
9255ee31 1326 lendiff <= prompt_visible_length || !current_invis_chars))
d60d9f65 1327 {
9255ee31
EZ
1328 insert_some_chars (nfd, lendiff, col_lendiff);
1329 _rl_last_c_pos += col_lendiff;
d60d9f65
SS
1330 }
1331 else if (*ols == 0)
1332 {
1333 /* At the end of a line the characters do not have to
1334 be "inserted". They can just be placed on the screen. */
1335 /* However, this screws up the rest of this block, which
c862e87b 1336 assumes you've done the insert because you can. */
d60d9f65 1337 _rl_output_some_chars (nfd, lendiff);
9255ee31 1338 _rl_last_c_pos += col_lendiff;
d60d9f65
SS
1339 }
1340 else
1341 {
1342 /* We have horizontal scrolling and we are not inserting at
1343 the end. We have invisible characters in this line. This
1344 is a dumb update. */
1345 _rl_output_some_chars (nfd, temp);
9255ee31 1346 _rl_last_c_pos += col_temp;
d60d9f65
SS
1347 return;
1348 }
1349 /* Copy (new) chars to screen from first diff to last match. */
1350 temp = nls - nfd;
1351 if ((temp - lendiff) > 0)
1352 {
1353 _rl_output_some_chars (nfd + lendiff, temp - lendiff);
9255ee31
EZ
1354#if 0
1355 _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff) - col_lendiff;
1356#else
1357 _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
1358#endif
d60d9f65
SS
1359 }
1360 }
1361 else
1362 {
1363 /* cannot insert chars, write to EOL */
1364 _rl_output_some_chars (nfd, temp);
9255ee31 1365 _rl_last_c_pos += col_temp;
d60d9f65
SS
1366 }
1367 }
1368 else /* Delete characters from line. */
1369 {
1370 /* If possible and inexpensive to use terminal deletion, then do so. */
9255ee31 1371 if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
d60d9f65
SS
1372 {
1373 /* If all we're doing is erasing the invisible characters in the
1374 prompt string, don't bother. It screws up the assumptions
1375 about what's on the screen. */
1376 if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
1377 -lendiff == visible_wrap_offset)
9255ee31 1378 col_lendiff = 0;
d60d9f65 1379
9255ee31
EZ
1380 if (col_lendiff)
1381 delete_chars (-col_lendiff); /* delete (diff) characters */
d60d9f65
SS
1382
1383 /* Copy (new) chars to screen from first diff to last match */
1384 temp = nls - nfd;
1385 if (temp > 0)
1386 {
1387 _rl_output_some_chars (nfd, temp);
9255ee31 1388 _rl_last_c_pos += _rl_col_width (nfd, 0, temp);;
d60d9f65
SS
1389 }
1390 }
1391 /* Otherwise, print over the existing material. */
1392 else
1393 {
1394 if (temp > 0)
1395 {
1396 _rl_output_some_chars (nfd, temp);
9255ee31 1397 _rl_last_c_pos += col_temp;
d60d9f65
SS
1398 }
1399 lendiff = (oe - old) - (ne - new);
9255ee31
EZ
1400 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1401 col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
1402 else
1403 col_lendiff = lendiff;
1404
1405 if (col_lendiff)
c862e87b
JM
1406 {
1407 if (_rl_term_autowrap && current_line < inv_botlin)
9255ee31 1408 space_to_eol (col_lendiff);
c862e87b 1409 else
9255ee31 1410 _rl_clear_to_eol (col_lendiff);
c862e87b 1411 }
d60d9f65
SS
1412 }
1413 }
1414}
1415
1416/* Tell the update routines that we have moved onto a new (empty) line. */
1417int
1418rl_on_new_line ()
1419{
1420 if (visible_line)
1421 visible_line[0] = '\0';
1422
1423 _rl_last_c_pos = _rl_last_v_pos = 0;
1424 _rl_vis_botlin = last_lmargin = 0;
1425 if (vis_lbreaks)
1426 vis_lbreaks[0] = vis_lbreaks[1] = 0;
1427 visible_wrap_offset = 0;
1428 return 0;
1429}
1430
1b17e766
EZ
1431/* Tell the update routines that we have moved onto a new line with the
1432 prompt already displayed. Code originally from the version of readline
1433 distributed with CLISP. */
1434int
1435rl_on_new_line_with_prompt ()
1436{
1437 int prompt_size, i, l, real_screenwidth, newlines;
1438 char *prompt_last_line;
1439
1440 /* Initialize visible_line and invisible_line to ensure that they can hold
1441 the already-displayed prompt. */
1442 prompt_size = strlen (rl_prompt) + 1;
1443 init_line_structures (prompt_size);
1444
1445 /* Make sure the line structures hold the already-displayed prompt for
1446 redisplay. */
1447 strcpy (visible_line, rl_prompt);
1448 strcpy (invisible_line, rl_prompt);
1449
1450 /* If the prompt contains newlines, take the last tail. */
1451 prompt_last_line = strrchr (rl_prompt, '\n');
1452 if (!prompt_last_line)
1453 prompt_last_line = rl_prompt;
1454
1455 l = strlen (prompt_last_line);
9255ee31
EZ
1456 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1457 _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l);
1458 else
1459 _rl_last_c_pos = l;
1b17e766
EZ
1460
1461 /* Dissect prompt_last_line into screen lines. Note that here we have
1462 to use the real screenwidth. Readline's notion of screenwidth might be
1463 one less, see terminal.c. */
9255ee31 1464 real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
1b17e766
EZ
1465 _rl_last_v_pos = l / real_screenwidth;
1466 /* If the prompt length is a multiple of real_screenwidth, we don't know
1467 whether the cursor is at the end of the last line, or already at the
1468 beginning of the next line. Output a newline just to be safe. */
1469 if (l > 0 && (l % real_screenwidth) == 0)
1470 _rl_output_some_chars ("\n", 1);
1471 last_lmargin = 0;
1472
1473 newlines = 0; i = 0;
1474 while (i <= l)
1475 {
1476 _rl_vis_botlin = newlines;
1477 vis_lbreaks[newlines++] = i;
1478 i += real_screenwidth;
1479 }
1480 vis_lbreaks[newlines] = l;
1481 visible_wrap_offset = 0;
1482
1483 return 0;
1484}
1485
d60d9f65
SS
1486/* Actually update the display, period. */
1487int
1488rl_forced_update_display ()
1489{
1490 if (visible_line)
1491 {
1492 register char *temp = visible_line;
1493
1494 while (*temp)
c862e87b 1495 *temp++ = '\0';
d60d9f65
SS
1496 }
1497 rl_on_new_line ();
1498 forced_display++;
1499 (*rl_redisplay_function) ();
1500 return 0;
1501}
1502
1503/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
1504 DATA is the contents of the screen line of interest; i.e., where
1505 the movement is being done. */
1506void
1507_rl_move_cursor_relative (new, data)
1508 int new;
9255ee31 1509 const char *data;
d60d9f65
SS
1510{
1511 register int i;
1512
1513 /* If we don't have to do anything, then return. */
9255ee31
EZ
1514#if defined (HANDLE_MULTIBYTE)
1515 /* If we have multibyte characters, NEW is indexed by the buffer point in
1516 a multibyte string, but _rl_last_c_pos is the display position. In
1517 this case, NEW's display position is not obvious. */
1518 if ((MB_CUR_MAX == 1 || rl_byte_oriented ) && _rl_last_c_pos == new) return;
1519#else
d60d9f65 1520 if (_rl_last_c_pos == new) return;
9255ee31 1521#endif
d60d9f65
SS
1522
1523 /* It may be faster to output a CR, and then move forwards instead
1524 of moving backwards. */
1525 /* i == current physical cursor position. */
1526 i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
1527 if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
9255ee31 1528 (_rl_term_autowrap && i == _rl_screenwidth))
d60d9f65
SS
1529 {
1530#if defined (__MSDOS__)
1531 putc ('\r', rl_outstream);
1532#else
9255ee31 1533 tputs (_rl_term_cr, 1, _rl_output_character_function);
d60d9f65
SS
1534#endif /* !__MSDOS__ */
1535 _rl_last_c_pos = 0;
1536 }
1537
1538 if (_rl_last_c_pos < new)
1539 {
1540 /* Move the cursor forward. We do it by printing the command
1541 to move the cursor forward if there is one, else print that
1542 portion of the output buffer again. Which is cheaper? */
1543
1544 /* The above comment is left here for posterity. It is faster
1545 to print one character (non-control) than to print a control
1546 sequence telling the terminal to move forward one character.
1547 That kind of control is for people who don't know what the
1548 data is underneath the cursor. */
1549#if defined (HACK_TERMCAP_MOTION)
9255ee31
EZ
1550 if (_rl_term_forward_char)
1551 {
1552 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1553 {
1554 int width;
1555 width = _rl_col_width (data, _rl_last_c_pos, new);
1556 for (i = 0; i < width; i++)
1557 tputs (_rl_term_forward_char, 1, _rl_output_character_function);
1558 }
1559 else
1560 {
1561 for (i = _rl_last_c_pos; i < new; i++)
1562 tputs (_rl_term_forward_char, 1, _rl_output_character_function);
1563 }
1564 }
1565 else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1566 {
1567 tputs (_rl_term_cr, 1, _rl_output_character_function);
1568 for (i = 0; i < new; i++)
1569 putc (data[i], rl_outstream);
1570 }
1571 else
d60d9f65 1572 for (i = _rl_last_c_pos; i < new; i++)
9255ee31
EZ
1573 putc (data[i], rl_outstream);
1574
1575#else /* !HACK_TERMCAP_MOTION */
1576
1577 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1578 {
1579 tputs (_rl_term_cr, 1, _rl_output_character_function);
1580 for (i = 0; i < new; i++)
1581 putc (data[i], rl_outstream);
1582 }
d60d9f65
SS
1583 else
1584 for (i = _rl_last_c_pos; i < new; i++)
1585 putc (data[i], rl_outstream);
9255ee31
EZ
1586
1587#endif /* !HACK_TERMCAP_MOTION */
1588
d60d9f65 1589 }
9255ee31
EZ
1590#if defined (HANDLE_MULTIBYTE)
1591 /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
1592 The byte length of the string is probably bigger than the column width
1593 of the string, which means that if NEW == _rl_last_c_pos, then NEW's
1594 display point is less than _rl_last_c_pos. */
1595 else if (_rl_last_c_pos >= new)
1596#else
c862e87b 1597 else if (_rl_last_c_pos > new)
9255ee31
EZ
1598#endif
1599 {
1600 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1601 {
1602 tputs (_rl_term_cr, 1, _rl_output_character_function);
1603 for (i = 0; i < new; i++)
1604 putc (data[i], rl_outstream);
1605 }
1606 else
1607 _rl_backspace (_rl_last_c_pos - new);
1608 }
1609
1610 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1611 _rl_last_c_pos = _rl_col_width (data, 0, new);
1612 else
1613 _rl_last_c_pos = new;
d60d9f65
SS
1614}
1615
1616/* PWP: move the cursor up or down. */
1617void
1618_rl_move_vert (to)
1619 int to;
1620{
1621 register int delta, i;
1622
9255ee31 1623 if (_rl_last_v_pos == to || to > _rl_screenheight)
d60d9f65
SS
1624 return;
1625
d60d9f65
SS
1626 if ((delta = to - _rl_last_v_pos) > 0)
1627 {
1628 for (i = 0; i < delta; i++)
1629 putc ('\n', rl_outstream);
1b17e766
EZ
1630#if defined (__MSDOS__)
1631 putc ('\r', rl_outstream);
1632#else
9255ee31 1633 tputs (_rl_term_cr, 1, _rl_output_character_function);
1b17e766 1634#endif
d60d9f65
SS
1635 _rl_last_c_pos = 0;
1636 }
1637 else
1638 { /* delta < 0 */
30083a32
EZ
1639#ifdef __MSDOS__
1640 int row, col;
1641
9255ee31 1642 l = fflush (rl_outstream); /* make sure the cursor pos is current! */
30083a32
EZ
1643 ScreenGetCursor (&row, &col);
1644 ScreenSetCursor ((row + to - _rl_last_v_pos), col);
1645 delta = i;
1646#else /* !__MSDOS__ */
9255ee31 1647 if (_rl_term_up && *_rl_term_up)
d60d9f65 1648 for (i = 0; i < -delta; i++)
9255ee31 1649 tputs (_rl_term_up, 1, _rl_output_character_function);
30083a32 1650#endif /* !__MSDOS__ */
d60d9f65 1651 }
1b17e766 1652
d60d9f65
SS
1653 _rl_last_v_pos = to; /* Now TO is here */
1654}
1655
1656/* Physically print C on rl_outstream. This is for functions which know
1657 how to optimize the display. Return the number of characters output. */
1658int
1659rl_show_char (c)
1660 int c;
1661{
1662 int n = 1;
1663 if (META_CHAR (c) && (_rl_output_meta_chars == 0))
1664 {
1665 fprintf (rl_outstream, "M-");
1666 n += 2;
1667 c = UNMETA (c);
1668 }
1669
1670#if defined (DISPLAY_TABS)
1671 if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
1672#else
1673 if (CTRL_CHAR (c) || c == RUBOUT)
1674#endif /* !DISPLAY_TABS */
1675 {
1676 fprintf (rl_outstream, "C-");
1677 n += 2;
1678 c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
1679 }
1680
1681 putc (c, rl_outstream);
1682 fflush (rl_outstream);
1683 return n;
1684}
1685
1686int
1687rl_character_len (c, pos)
1688 register int c, pos;
1689{
1690 unsigned char uc;
1691
1692 uc = (unsigned char)c;
1693
1694 if (META_CHAR (uc))
1695 return ((_rl_output_meta_chars == 0) ? 4 : 1);
1696
1697 if (uc == '\t')
1698 {
1699#if defined (DISPLAY_TABS)
1700 return (((pos | 7) + 1) - pos);
1701#else
1702 return (2);
1703#endif /* !DISPLAY_TABS */
1704 }
1705
1706 if (CTRL_CHAR (c) || c == RUBOUT)
1707 return (2);
1708
9255ee31 1709 return ((ISPRINT (uc)) ? 1 : 2);
d60d9f65
SS
1710}
1711
1712/* How to print things in the "echo-area". The prompt is treated as a
1713 mini-modeline. */
1714
1715#if defined (USE_VARARGS)
1716int
1717#if defined (PREFER_STDARG)
1718rl_message (const char *format, ...)
1719#else
1720rl_message (va_alist)
1721 va_dcl
1722#endif
1723{
1724 va_list args;
1725#if defined (PREFER_VARARGS)
1726 char *format;
1727#endif
1728
1729#if defined (PREFER_STDARG)
1730 va_start (args, format);
1731#else
1732 va_start (args);
1733 format = va_arg (args, char *);
1734#endif
1735
9255ee31
EZ
1736#if defined (HAVE_VSNPRINTF)
1737 vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
1738#else
d60d9f65 1739 vsprintf (msg_buf, format, args);
9255ee31
EZ
1740 msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
1741#endif
d60d9f65
SS
1742 va_end (args);
1743
1744 rl_display_prompt = msg_buf;
1745 (*rl_redisplay_function) ();
1746 return 0;
1747}
1748#else /* !USE_VARARGS */
1749int
1750rl_message (format, arg1, arg2)
1751 char *format;
1752{
1753 sprintf (msg_buf, format, arg1, arg2);
9255ee31 1754 msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
d60d9f65
SS
1755 rl_display_prompt = msg_buf;
1756 (*rl_redisplay_function) ();
1757 return 0;
1758}
1759#endif /* !USE_VARARGS */
1760
1761/* How to clear things from the "echo-area". */
1762int
1763rl_clear_message ()
1764{
1765 rl_display_prompt = rl_prompt;
1766 (*rl_redisplay_function) ();
1767 return 0;
1768}
1769
1770int
1771rl_reset_line_state ()
1772{
1773 rl_on_new_line ();
1774
1775 rl_display_prompt = rl_prompt ? rl_prompt : "";
1776 forced_display = 1;
1777 return 0;
1778}
1779
1780static char *saved_local_prompt;
1781static char *saved_local_prefix;
1782static int saved_last_invisible;
1783static int saved_visible_length;
1784
1785void
c862e87b 1786rl_save_prompt ()
d60d9f65
SS
1787{
1788 saved_local_prompt = local_prompt;
1789 saved_local_prefix = local_prompt_prefix;
9255ee31
EZ
1790 saved_last_invisible = prompt_last_invisible;
1791 saved_visible_length = prompt_visible_length;
d60d9f65
SS
1792
1793 local_prompt = local_prompt_prefix = (char *)0;
9255ee31 1794 prompt_last_invisible = prompt_visible_length = 0;
d60d9f65
SS
1795}
1796
1797void
c862e87b 1798rl_restore_prompt ()
d60d9f65 1799{
9255ee31
EZ
1800 FREE (local_prompt);
1801 FREE (local_prompt_prefix);
d60d9f65
SS
1802
1803 local_prompt = saved_local_prompt;
1804 local_prompt_prefix = saved_local_prefix;
9255ee31
EZ
1805 prompt_last_invisible = saved_last_invisible;
1806 prompt_visible_length = saved_visible_length;
d60d9f65
SS
1807}
1808
1809char *
1810_rl_make_prompt_for_search (pchar)
1811 int pchar;
1812{
1813 int len;
1814 char *pmt;
1815
c862e87b 1816 rl_save_prompt ();
d60d9f65
SS
1817
1818 if (saved_local_prompt == 0)
1819 {
1820 len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
9255ee31 1821 pmt = (char *)xmalloc (len + 2);
d60d9f65 1822 if (len)
c862e87b 1823 strcpy (pmt, rl_prompt);
d60d9f65
SS
1824 pmt[len] = pchar;
1825 pmt[len+1] = '\0';
1826 }
1827 else
1828 {
1829 len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
9255ee31 1830 pmt = (char *)xmalloc (len + 2);
d60d9f65 1831 if (len)
c862e87b 1832 strcpy (pmt, saved_local_prompt);
d60d9f65
SS
1833 pmt[len] = pchar;
1834 pmt[len+1] = '\0';
1835 local_prompt = savestring (pmt);
9255ee31
EZ
1836 prompt_last_invisible = saved_last_invisible;
1837 prompt_visible_length = saved_visible_length + 1;
d60d9f65
SS
1838 }
1839 return pmt;
1840}
1841
1842/* Quick redisplay hack when erasing characters at the end of the line. */
1843void
1844_rl_erase_at_end_of_line (l)
1845 int l;
1846{
1847 register int i;
1848
1849 _rl_backspace (l);
1850 for (i = 0; i < l; i++)
1851 putc (' ', rl_outstream);
1852 _rl_backspace (l);
1853 for (i = 0; i < l; i++)
1854 visible_line[--_rl_last_c_pos] = '\0';
1855 rl_display_fixed++;
1856}
1857
1858/* Clear to the end of the line. COUNT is the minimum
1859 number of character spaces to clear, */
1860void
1861_rl_clear_to_eol (count)
1862 int count;
1863{
30083a32 1864#ifndef __MSDOS__
9255ee31
EZ
1865 if (_rl_term_clreol)
1866 tputs (_rl_term_clreol, 1, _rl_output_character_function);
30083a32
EZ
1867 else
1868#endif
1869 if (count)
d60d9f65
SS
1870 space_to_eol (count);
1871}
1872
1873/* Clear to the end of the line using spaces. COUNT is the minimum
1874 number of character spaces to clear, */
1875static void
1876space_to_eol (count)
1877 int count;
1878{
1879 register int i;
1880
1881 for (i = 0; i < count; i++)
1882 putc (' ', rl_outstream);
1883
1884 _rl_last_c_pos += count;
1885}
1886
1887void
1888_rl_clear_screen ()
1889{
30083a32
EZ
1890#if defined (__GO32__)
1891 ScreenClear (); /* FIXME: only works in text modes */
1892 ScreenSetCursor (0, 0); /* term_clrpag is "cl" which homes the cursor */
1893#else
9255ee31
EZ
1894 if (_rl_term_clrpag)
1895 tputs (_rl_term_clrpag, 1, _rl_output_character_function);
d60d9f65 1896 else
9255ee31 1897 rl_crlf ();
30083a32 1898#endif
d60d9f65
SS
1899}
1900
9255ee31 1901/* Insert COUNT characters from STRING to the output stream at column COL. */
d60d9f65 1902static void
9255ee31 1903insert_some_chars (string, count, col)
d60d9f65 1904 char *string;
9255ee31 1905 int count, col;
d60d9f65 1906{
30083a32
EZ
1907#ifdef __MSDOS__
1908 _rl_output_some_chars (string, count);
1909#else /* !__MSDOS__ */
9255ee31
EZ
1910 /* DEBUGGING */
1911 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1912 if (count != col)
1913 fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col);
1914
d60d9f65 1915 /* If IC is defined, then we do not have to "enter" insert mode. */
9255ee31 1916 if (_rl_term_IC)
d60d9f65
SS
1917 {
1918 char *buffer;
9255ee31
EZ
1919
1920 buffer = tgoto (_rl_term_IC, 0, col);
d60d9f65
SS
1921 tputs (buffer, 1, _rl_output_character_function);
1922 _rl_output_some_chars (string, count);
1923 }
1924 else
1925 {
1926 register int i;
1927
1928 /* If we have to turn on insert-mode, then do so. */
9255ee31
EZ
1929 if (_rl_term_im && *_rl_term_im)
1930 tputs (_rl_term_im, 1, _rl_output_character_function);
d60d9f65
SS
1931
1932 /* If there is a special command for inserting characters, then
1933 use that first to open up the space. */
9255ee31 1934 if (_rl_term_ic && *_rl_term_ic)
d60d9f65 1935 {
9255ee31
EZ
1936 for (i = col; i--; )
1937 tputs (_rl_term_ic, 1, _rl_output_character_function);
d60d9f65
SS
1938 }
1939
1940 /* Print the text. */
1941 _rl_output_some_chars (string, count);
1942
1943 /* If there is a string to turn off insert mode, we had best use
1944 it now. */
9255ee31
EZ
1945 if (_rl_term_ei && *_rl_term_ei)
1946 tputs (_rl_term_ei, 1, _rl_output_character_function);
d60d9f65 1947 }
30083a32 1948#endif /* !__MSDOS__ */
d60d9f65
SS
1949}
1950
1951/* Delete COUNT characters from the display line. */
1952static void
1953delete_chars (count)
1954 int count;
1955{
9255ee31 1956 if (count > _rl_screenwidth) /* XXX */
d60d9f65
SS
1957 return;
1958
30083a32 1959#ifndef __MSDOS__
9255ee31 1960 if (_rl_term_DC && *_rl_term_DC)
d60d9f65
SS
1961 {
1962 char *buffer;
9255ee31 1963 buffer = tgoto (_rl_term_DC, count, count);
d60d9f65
SS
1964 tputs (buffer, count, _rl_output_character_function);
1965 }
1966 else
1967 {
9255ee31 1968 if (_rl_term_dc && *_rl_term_dc)
d60d9f65 1969 while (count--)
9255ee31 1970 tputs (_rl_term_dc, 1, _rl_output_character_function);
d60d9f65 1971 }
30083a32 1972#endif /* !__MSDOS__ */
d60d9f65
SS
1973}
1974
1975void
1976_rl_update_final ()
1977{
1978 int full_lines;
1979
1980 full_lines = 0;
1981 /* If the cursor is the only thing on an otherwise-blank last line,
1982 compensate so we don't print an extra CRLF. */
1983 if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
1984 visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
1985 {
1986 _rl_vis_botlin--;
1987 full_lines = 1;
1988 }
1989 _rl_move_vert (_rl_vis_botlin);
1990 /* If we've wrapped lines, remove the final xterm line-wrap flag. */
9255ee31 1991 if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
d60d9f65
SS
1992 {
1993 char *last_line;
9255ee31 1994
1b17e766 1995 last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
9255ee31 1996 _rl_move_cursor_relative (_rl_screenwidth - 1, last_line);
d60d9f65 1997 _rl_clear_to_eol (0);
9255ee31 1998 putc (last_line[_rl_screenwidth - 1], rl_outstream);
d60d9f65
SS
1999 }
2000 _rl_vis_botlin = 0;
9255ee31 2001 rl_crlf ();
d60d9f65
SS
2002 fflush (rl_outstream);
2003 rl_display_fixed++;
2004}
2005
2006/* Move to the start of the current line. */
2007static void
2008cr ()
2009{
9255ee31 2010 if (_rl_term_cr)
d60d9f65 2011 {
771578d1
SS
2012#if defined (__MSDOS__)
2013 putc ('\r', rl_outstream);
2014#else
9255ee31 2015 tputs (_rl_term_cr, 1, _rl_output_character_function);
1b17e766 2016#endif
d60d9f65
SS
2017 _rl_last_c_pos = 0;
2018 }
2019}
2020
1b17e766
EZ
2021/* Redraw the last line of a multi-line prompt that may possibly contain
2022 terminal escape sequences. Called with the cursor at column 0 of the
2023 line to draw the prompt on. */
2024static void
2025redraw_prompt (t)
2026 char *t;
2027{
2028 char *oldp, *oldl, *oldlprefix;
9255ee31 2029 int oldlen, oldlast, oldplen, oldninvis;
1b17e766
EZ
2030
2031 /* Geez, I should make this a struct. */
2032 oldp = rl_display_prompt;
2033 oldl = local_prompt;
2034 oldlprefix = local_prompt_prefix;
9255ee31
EZ
2035 oldlen = prompt_visible_length;
2036 oldplen = prompt_prefix_length;
2037 oldlast = prompt_last_invisible;
2038 oldninvis = prompt_invis_chars_first_line;
1b17e766
EZ
2039
2040 rl_display_prompt = t;
9255ee31
EZ
2041 local_prompt = expand_prompt (t, &prompt_visible_length,
2042 &prompt_last_invisible,
2043 &prompt_invis_chars_first_line);
1b17e766
EZ
2044 local_prompt_prefix = (char *)NULL;
2045 rl_forced_update_display ();
2046
2047 rl_display_prompt = oldp;
2048 local_prompt = oldl;
2049 local_prompt_prefix = oldlprefix;
9255ee31
EZ
2050 prompt_visible_length = oldlen;
2051 prompt_prefix_length = oldplen;
2052 prompt_last_invisible = oldlast;
2053 prompt_invis_chars_first_line = oldninvis;
1b17e766
EZ
2054}
2055
d60d9f65
SS
2056/* Redisplay the current line after a SIGWINCH is received. */
2057void
2058_rl_redisplay_after_sigwinch ()
2059{
1b17e766 2060 char *t;
d60d9f65
SS
2061
2062 /* Clear the current line and put the cursor at column 0. Make sure
2063 the right thing happens if we have wrapped to a new screen line. */
9255ee31 2064 if (_rl_term_cr)
d60d9f65 2065 {
771578d1
SS
2066#if defined (__MSDOS__)
2067 putc ('\r', rl_outstream);
2068#else
9255ee31 2069 tputs (_rl_term_cr, 1, _rl_output_character_function);
1b17e766 2070#endif
d60d9f65 2071 _rl_last_c_pos = 0;
771578d1 2072#if defined (__MSDOS__)
9255ee31 2073 space_to_eol (_rl_screenwidth);
771578d1
SS
2074 putc ('\r', rl_outstream);
2075#else
9255ee31
EZ
2076 if (_rl_term_clreol)
2077 tputs (_rl_term_clreol, 1, _rl_output_character_function);
d60d9f65
SS
2078 else
2079 {
9255ee31
EZ
2080 space_to_eol (_rl_screenwidth);
2081 tputs (_rl_term_cr, 1, _rl_output_character_function);
d60d9f65 2082 }
771578d1 2083#endif
d60d9f65
SS
2084 if (_rl_last_v_pos > 0)
2085 _rl_move_vert (0);
2086 }
2087 else
9255ee31 2088 rl_crlf ();
d60d9f65
SS
2089
2090 /* Redraw only the last line of a multi-line prompt. */
2091 t = strrchr (rl_display_prompt, '\n');
2092 if (t)
1b17e766 2093 redraw_prompt (++t);
d60d9f65
SS
2094 else
2095 rl_forced_update_display ();
2096}
2097
2098void
2099_rl_clean_up_for_exit ()
2100{
2101 if (readline_echoing_p)
2102 {
2103 _rl_move_vert (_rl_vis_botlin);
2104 _rl_vis_botlin = 0;
2105 fflush (rl_outstream);
c862e87b 2106 rl_restart_output (1, 0);
d60d9f65
SS
2107 }
2108}
c862e87b
JM
2109
2110void
2111_rl_erase_entire_line ()
2112{
2113 cr ();
2114 _rl_clear_to_eol (0);
2115 cr ();
2116 fflush (rl_outstream);
2117}
1b17e766
EZ
2118
2119/* return the `current display line' of the cursor -- the number of lines to
2120 move up to get to the first screen line of the current readline line. */
2121int
2122_rl_current_display_line ()
2123{
2124 int ret, nleft;
2125
2126 /* Find out whether or not there might be invisible characters in the
2127 editing buffer. */
2128 if (rl_display_prompt == rl_prompt)
9255ee31 2129 nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
1b17e766 2130 else
9255ee31 2131 nleft = _rl_last_c_pos - _rl_screenwidth;
1b17e766
EZ
2132
2133 if (nleft > 0)
9255ee31 2134 ret = 1 + nleft / _rl_screenwidth;
1b17e766
EZ
2135 else
2136 ret = 0;
2137
2138 return ret;
2139}
9255ee31
EZ
2140
2141#if defined (HANDLE_MULTIBYTE)
2142/* Calculate the number of screen columns occupied by STR from START to END.
2143 In the case of multibyte characters with stateful encoding, we have to
2144 scan from the beginning of the string to take the state into account. */
2145static int
2146_rl_col_width (str, start, end)
2147 char *str;
2148 int start, end;
2149{
2150 wchar_t wc;
2151 mbstate_t ps = {0};
2152 int tmp, point, width, max;
2153
2154 if (end <= start)
2155 return 0;
2156
2157 point = 0;
2158 max = end;
2159
2160 while (point < start)
2161 {
2162 tmp = mbrlen (str + point, max, &ps);
2163 if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
2164 {
2165 /* In this case, the bytes are invalid or too short to compose a
2166 multibyte character, so we assume that the first byte represents
2167 a single character. */
2168 point++;
2169 max--;
2170
2171 /* Clear the state of the byte sequence, because in this case the
2172 effect of mbstate is undefined. */
2173 memset (&ps, 0, sizeof (mbstate_t));
2174 }
2175 else if (tmp == 0)
2176 break; /* Found '\0' */
2177 else
2178 {
2179 point += tmp;
2180 max -= tmp;
2181 }
2182 }
2183
2184 /* If START is not a byte that starts a character, then POINT will be
2185 greater than START. In this case, assume that (POINT - START) gives
2186 a byte count that is the number of columns of difference. */
2187 width = point - start;
2188
2189 while (point < end)
2190 {
2191 tmp = mbrtowc (&wc, str + point, max, &ps);
2192 if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
2193 {
2194 /* In this case, the bytes are invalid or too short to compose a
2195 multibyte character, so we assume that the first byte represents
2196 a single character. */
2197 point++;
2198 max--;
2199
2200 /* and assume that the byte occupies a single column. */
2201 width++;
2202
2203 /* Clear the state of the byte sequence, because in this case the
2204 effect of mbstate is undefined. */
2205 memset (&ps, 0, sizeof (mbstate_t));
2206 }
2207 else if (tmp == 0)
2208 break; /* Found '\0' */
2209 else
2210 {
2211 point += tmp;
2212 max -= tmp;
2213 tmp = wcwidth(wc);
2214 width += (tmp >= 0) ? tmp : 1;
2215 }
2216 }
2217
2218 width += point - end;
2219
2220 return width;
2221}
2222#endif /* HANDLE_MULTIBYTE */
2223
This page took 0.249792 seconds and 4 git commands to generate.