]> git.ipfire.org Git - thirdparty/bash.git/blame_incremental - lib/readline/display.c
bash-4.4 beta release
[thirdparty/bash.git] / lib / readline / display.c
... / ...
CommitLineData
1/* display.c -- readline redisplay facility. */
2
3/* Copyright (C) 1987-2013 Free Software Foundation, Inc.
4
5 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
7
8 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
20*/
21
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#ifdef __MSDOS__
45# include <pc.h>
46#endif
47
48/* System-specific feature definitions and include files. */
49#include "rldefs.h"
50#include "rlmbutil.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#include "rlprivate.h"
60#include "xmalloc.h"
61
62#if !defined (strchr) && !defined (__STDC__)
63extern char *strchr (), *strrchr ();
64#endif /* !strchr && !__STDC__ */
65
66static void update_line PARAMS((char *, char *, int, int, int, int));
67static void space_to_eol PARAMS((int));
68static void delete_chars PARAMS((int));
69static void insert_some_chars PARAMS((char *, int, int));
70static void open_some_spaces PARAMS((int));
71static void cr PARAMS((void));
72static void redraw_prompt PARAMS((char *));
73
74/* Values for FLAGS */
75#define PMT_MULTILINE 0x01
76
77static char *expand_prompt PARAMS((char *, int, int *, int *, int *, int *));
78
79/* State of visible and invisible lines. */
80struct line_state
81 {
82 char *line;
83 int *lbreaks;
84 int lbsize;
85#if defined (HANDLE_MULTIBYTE)
86 int wbsize;
87 int *wrapped_line;
88#endif
89 };
90
91/* The line display buffers. One is the line currently displayed on
92 the screen. The other is the line about to be displayed. */
93static struct line_state line_state_array[2];
94static struct line_state *line_state_visible = &line_state_array[0];
95static struct line_state *line_state_invisible = &line_state_array[1];
96static int line_structures_initialized = 0;
97
98/* Backwards-compatible names. */
99#define inv_lbreaks (line_state_invisible->lbreaks)
100#define inv_lbsize (line_state_invisible->lbsize)
101#define vis_lbreaks (line_state_visible->lbreaks)
102#define vis_lbsize (line_state_visible->lbsize)
103
104#define visible_line (line_state_visible->line)
105#define invisible_line (line_state_invisible->line)
106
107#if defined (HANDLE_MULTIBYTE)
108static int _rl_col_width PARAMS((const char *, int, int, int));
109#else
110# define _rl_col_width(l, s, e, f) (((e) <= (s)) ? 0 : (e) - (s))
111#endif
112
113/* Heuristic used to decide whether it is faster to move from CUR to NEW
114 by backing up or outputting a carriage return and moving forward. CUR
115 and NEW are either both buffer positions or absolute screen positions. */
116#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
117
118/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
119 buffer index in others. This macro is used when deciding whether the
120 current cursor position is in the middle of a prompt string containing
121 invisible characters. XXX - might need to take `modmark' into account. */
122#define PROMPT_ENDING_INDEX \
123 ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
124
125
126/* **************************************************************** */
127/* */
128/* Display stuff */
129/* */
130/* **************************************************************** */
131
132/* This is the stuff that is hard for me. I never seem to write good
133 display routines in C. Let's see how I do this time. */
134
135/* (PWP) Well... Good for a simple line updater, but totally ignores
136 the problems of input lines longer than the screen width.
137
138 update_line and the code that calls it makes a multiple line,
139 automatically wrapping line update. Careful attention needs
140 to be paid to the vertical position variables. */
141
142/* Keep two buffers; one which reflects the current contents of the
143 screen, and the other to draw what we think the new contents should
144 be. Then compare the buffers, and make whatever changes to the
145 screen itself that we should. Finally, make the buffer that we
146 just drew into be the one which reflects the current contents of the
147 screen, and place the cursor where it belongs.
148
149 Commands that want to can fix the display themselves, and then let
150 this function know that the display has been fixed by setting the
151 RL_DISPLAY_FIXED variable. This is good for efficiency. */
152
153/* Application-specific redisplay function. */
154rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
155
156/* Global variables declared here. */
157/* What YOU turn on when you have handled all redisplay yourself. */
158int rl_display_fixed = 0;
159
160int _rl_suppress_redisplay = 0;
161int _rl_want_redisplay = 0;
162
163/* The stuff that gets printed out before the actual text of the line.
164 This is usually pointing to rl_prompt. */
165char *rl_display_prompt = (char *)NULL;
166
167/* Variables used to include the editing mode in the prompt. */
168char *_rl_emacs_mode_str;
169int _rl_emacs_modestr_len;
170
171char *_rl_vi_ins_mode_str;
172int _rl_vi_ins_modestr_len;
173
174char *_rl_vi_cmd_mode_str;
175int _rl_vi_cmd_modestr_len;
176
177/* Pseudo-global variables declared here. */
178
179/* The visible cursor position. If you print some text, adjust this. */
180/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
181 supporting multibyte characters, and an absolute cursor position when
182 in such a locale. This is an artifact of the donated multibyte support.
183 Care must be taken when modifying its value. */
184int _rl_last_c_pos = 0;
185int _rl_last_v_pos = 0;
186
187static int cpos_adjusted;
188static int cpos_buffer_position;
189static int displaying_prompt_first_line;
190static int prompt_multibyte_chars;
191
192/* Number of lines currently on screen minus 1. */
193int _rl_vis_botlin = 0;
194
195/* Variables used only in this file. */
196/* The last left edge of text that was displayed. This is used when
197 doing horizontal scrolling. It shifts in thirds of a screenwidth. */
198static int last_lmargin;
199
200/* A buffer for `modeline' messages. */
201static char *msg_buf = 0;
202static int msg_bufsiz = 0;
203
204/* Non-zero forces the redisplay even if we thought it was unnecessary. */
205static int forced_display;
206
207/* Default and initial buffer size. Can grow. */
208static int line_size = 1024;
209
210/* Variables to keep track of the expanded prompt string, which may
211 include invisible characters. */
212
213static char *local_prompt, *local_prompt_prefix;
214static int local_prompt_len;
215static int prompt_visible_length, prompt_prefix_length;
216
217/* The number of invisible characters in the line currently being
218 displayed on the screen. */
219static int visible_wrap_offset;
220
221/* The number of invisible characters in the prompt string. Static so it
222 can be shared between rl_redisplay and update_line */
223static int wrap_offset;
224
225/* The index of the last invisible character in the prompt string. */
226static int prompt_last_invisible;
227
228/* The length (buffer offset) of the first line of the last (possibly
229 multi-line) buffer displayed on the screen. */
230static int visible_first_line_len;
231
232/* Number of invisible characters on the first physical line of the prompt.
233 Only valid when the number of physical characters in the prompt exceeds
234 (or is equal to) _rl_screenwidth. */
235static int prompt_invis_chars_first_line;
236
237static int prompt_last_screen_line;
238
239static int prompt_physical_chars;
240
241/* set to a non-zero value by rl_redisplay if we are marking modified history
242 lines and the current line is so marked. */
243static int modmark;
244
245/* Variables to save and restore prompt and display information. */
246
247/* These are getting numerous enough that it's time to create a struct. */
248
249static char *saved_local_prompt;
250static char *saved_local_prefix;
251static int saved_last_invisible;
252static int saved_visible_length;
253static int saved_prefix_length;
254static int saved_local_length;
255static int saved_invis_chars_first_line;
256static int saved_physical_chars;
257
258/* Return a string indicating the editing mode, for use in the prompt. */
259
260static char *
261prompt_modestr (lenp)
262 int *lenp;
263{
264 if (rl_editing_mode == emacs_mode)
265 {
266 if (lenp)
267 *lenp = _rl_emacs_mode_str ? _rl_emacs_modestr_len : RL_EMACS_MODESTR_DEFLEN;
268 return _rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT;
269 }
270 else if (_rl_keymap == vi_insertion_keymap)
271 {
272 if (lenp)
273 *lenp = _rl_vi_ins_mode_str ? _rl_vi_ins_modestr_len : RL_VI_INS_MODESTR_DEFLEN;
274 return _rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT; /* vi insert mode */
275 }
276 else
277 {
278 if (lenp)
279 *lenp = _rl_vi_cmd_mode_str ? _rl_vi_cmd_modestr_len : RL_VI_CMD_MODESTR_DEFLEN;
280 return _rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT; /* vi command mode */
281 }
282}
283
284/* Expand the prompt string S and return the number of visible
285 characters in *LP, if LP is not null. This is currently more-or-less
286 a placeholder for expansion. LIP, if non-null is a place to store the
287 index of the last invisible character in the returned string. NIFLP,
288 if non-zero, is a place to store the number of invisible characters in
289 the first prompt line. The previous are used as byte counts -- indexes
290 into a character buffer. */
291
292/* Current implementation:
293 \001 (^A) start non-visible characters
294 \002 (^B) end non-visible characters
295 all characters except \001 and \002 (following a \001) are copied to
296 the returned string; all characters except those between \001 and
297 \002 are assumed to be `visible'. */
298
299/* Possible values for FLAGS:
300 PMT_MULTILINE caller indicates that this is part of a multiline prompt
301*/
302
303static char *
304expand_prompt (pmt, flags, lp, lip, niflp, vlp)
305 char *pmt;
306 int flags;
307 int *lp, *lip, *niflp, *vlp;
308{
309 char *r, *ret, *p, *igstart, *nprompt, *ms;
310 int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
311 int mlen;
312
313 /* We only expand the mode string for the last line of a multiline prompt
314 (a prompt with embedded newlines). */
315 ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0;
316 if (ms)
317 {
318 l = strlen (pmt);
319 nprompt = (char *)xmalloc (l + mlen + 1);
320 memcpy (nprompt, ms, mlen);
321 strcpy (nprompt + mlen, pmt);
322 }
323 else
324 nprompt = pmt;
325
326 /* Short-circuit if we can. */
327 if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (nprompt, RL_PROMPT_START_IGNORE) == 0)
328 {
329 r = (nprompt == pmt) ? savestring (pmt) : nprompt;
330
331 if (lp)
332 *lp = strlen (r);
333 if (lip)
334 *lip = 0;
335 if (niflp)
336 *niflp = 0;
337 if (vlp)
338 *vlp = lp ? *lp : strlen (r);
339 return r;
340 }
341
342 l = strlen (nprompt); /* XXX */
343 r = ret = (char *)xmalloc (l + 1);
344
345 rl = physchars = 0; /* mode string now part of nprompt */
346 invfl = 0; /* invisible chars in first line of prompt */
347 invflset = 0; /* we only want to set invfl once */
348 igstart = 0;
349
350 for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++)
351 {
352 /* This code strips the invisible character string markers
353 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
354 if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
355 {
356 ignoring = 1;
357 igstart = p;
358 continue;
359 }
360 else if (ignoring && *p == RL_PROMPT_END_IGNORE)
361 {
362 ignoring = 0;
363 if (p != (igstart + 1))
364 last = r - ret - 1;
365 continue;
366 }
367 else
368 {
369#if defined (HANDLE_MULTIBYTE)
370 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
371 {
372 pind = p - nprompt;
373 ind = _rl_find_next_mbchar (nprompt, pind, 1, MB_FIND_NONZERO);
374 l = ind - pind;
375 while (l--)
376 *r++ = *p++;
377 if (!ignoring)
378 {
379 /* rl ends up being assigned to prompt_visible_length,
380 which is the number of characters in the buffer that
381 contribute to characters on the screen, which might
382 not be the same as the number of physical characters
383 on the screen in the presence of multibyte characters */
384 rl += ind - pind;
385 physchars += _rl_col_width (nprompt, pind, ind, 0);
386 }
387 else
388 ninvis += ind - pind;
389 p--; /* compensate for later increment */
390 }
391 else
392#endif
393 {
394 *r++ = *p;
395 if (!ignoring)
396 {
397 rl++; /* visible length byte counter */
398 physchars++;
399 }
400 else
401 ninvis++; /* invisible chars byte counter */
402 }
403
404 if (invflset == 0 && rl >= _rl_screenwidth)
405 {
406 invfl = ninvis;
407 invflset = 1;
408 }
409 }
410 }
411
412 if (rl < _rl_screenwidth)
413 invfl = ninvis;
414
415 *r = '\0';
416 if (lp)
417 *lp = rl;
418 if (lip)
419 *lip = last;
420 if (niflp)
421 *niflp = invfl;
422 if (vlp)
423 *vlp = physchars;
424
425 if (nprompt != pmt)
426 free (nprompt);
427
428 return ret;
429}
430
431/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
432 PMT and return the rest of PMT. */
433char *
434_rl_strip_prompt (pmt)
435 char *pmt;
436{
437 char *ret;
438
439 ret = expand_prompt (pmt, 0, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
440 return ret;
441}
442
443void
444_rl_reset_prompt ()
445{
446 rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
447}
448
449/*
450 * Expand the prompt string into the various display components, if
451 * necessary.
452 *
453 * local_prompt = expanded last line of string in rl_display_prompt
454 * (portion after the final newline)
455 * local_prompt_prefix = portion before last newline of rl_display_prompt,
456 * expanded via expand_prompt
457 * prompt_visible_length = number of visible characters in local_prompt
458 * prompt_prefix_length = number of visible characters in local_prompt_prefix
459 *
460 * This function is called once per call to readline(). It may also be
461 * called arbitrarily to expand the primary prompt.
462 *
463 * The return value is the number of visible characters on the last line
464 * of the (possibly multi-line) prompt.
465 */
466int
467rl_expand_prompt (prompt)
468 char *prompt;
469{
470 char *p, *t;
471 int c;
472
473 /* Clear out any saved values. */
474 FREE (local_prompt);
475 FREE (local_prompt_prefix);
476
477 local_prompt = local_prompt_prefix = (char *)0;
478 local_prompt_len = 0;
479 prompt_last_invisible = prompt_invis_chars_first_line = 0;
480 prompt_visible_length = prompt_physical_chars = 0;
481
482 if (prompt == 0 || *prompt == 0)
483 return (0);
484
485 p = strrchr (prompt, '\n');
486 if (p == 0)
487 {
488 /* The prompt is only one logical line, though it might wrap. */
489 local_prompt = expand_prompt (prompt, 0, &prompt_visible_length,
490 &prompt_last_invisible,
491 &prompt_invis_chars_first_line,
492 &prompt_physical_chars);
493 local_prompt_prefix = (char *)0;
494 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
495 return (prompt_visible_length);
496 }
497 else
498 {
499 /* The prompt spans multiple lines. */
500 t = ++p;
501 local_prompt = expand_prompt (p, PMT_MULTILINE,
502 &prompt_visible_length,
503 &prompt_last_invisible,
504 &prompt_invis_chars_first_line,
505 &prompt_physical_chars);
506 c = *t; *t = '\0';
507 /* The portion of the prompt string up to and including the
508 final newline is now null-terminated. */
509 local_prompt_prefix = expand_prompt (prompt, PMT_MULTILINE,
510 &prompt_prefix_length,
511 (int *)NULL,
512 (int *)NULL,
513 (int *)NULL);
514 *t = c;
515 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
516 return (prompt_prefix_length);
517 }
518}
519
520/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
521 arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
522 and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
523 increased. If the lines have already been allocated, this ensures that
524 they can hold at least MINSIZE characters. */
525static void
526init_line_structures (minsize)
527 int minsize;
528{
529 register int n;
530
531 if (invisible_line == 0) /* initialize it */
532 {
533 if (line_size < minsize)
534 line_size = minsize;
535 visible_line = (char *)xmalloc (line_size);
536 invisible_line = (char *)xmalloc (line_size);
537 }
538 else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
539 {
540 line_size *= 2;
541 if (line_size < minsize)
542 line_size = minsize;
543 visible_line = (char *)xrealloc (visible_line, line_size);
544 invisible_line = (char *)xrealloc (invisible_line, line_size);
545 }
546
547 for (n = minsize; n < line_size; n++)
548 {
549 visible_line[n] = 0;
550 invisible_line[n] = 1;
551 }
552
553 if (vis_lbreaks == 0)
554 {
555 /* should be enough. */
556 inv_lbsize = vis_lbsize = 256;
557
558#if defined (HANDLE_MULTIBYTE)
559 line_state_visible->wbsize = vis_lbsize;
560 line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
561
562 line_state_invisible->wbsize = inv_lbsize;
563 line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
564#endif
565
566 inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
567 vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
568 inv_lbreaks[0] = vis_lbreaks[0] = 0;
569 }
570
571 line_structures_initialized = 1;
572}
573
574/* Basic redisplay algorithm. */
575void
576rl_redisplay ()
577{
578 register int in, out, c, linenum, cursor_linenum;
579 register char *line;
580 int inv_botlin, lb_botlin, lb_linenum, o_cpos;
581 int newlines, lpos, temp, n0, num, prompt_lines_estimate;
582 char *prompt_this_line;
583#if defined (HANDLE_MULTIBYTE)
584 wchar_t wc;
585 size_t wc_bytes;
586 int wc_width;
587 mbstate_t ps;
588 int _rl_wrapped_multicolumn = 0;
589 int mb_cur_max = MB_CUR_MAX;
590#endif
591
592 if (_rl_echoing_p == 0)
593 return;
594
595 /* Block keyboard interrupts because this function manipulates global
596 data structures. */
597 _rl_block_sigint ();
598 RL_SETSTATE (RL_STATE_REDISPLAYING);
599
600 if (!rl_display_prompt)
601 rl_display_prompt = "";
602
603 if (line_structures_initialized == 0)
604 {
605 init_line_structures (0);
606 rl_on_new_line ();
607 }
608
609 /* Draw the line into the buffer. */
610 cpos_buffer_position = -1;
611
612 prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
613
614 line = invisible_line;
615 out = inv_botlin = 0;
616
617 /* Mark the line as modified or not. We only do this for history
618 lines. */
619 modmark = 0;
620 if (_rl_mark_modified_lines && current_history () && rl_undo_list)
621 {
622 line[out++] = '*';
623 line[out] = '\0';
624 modmark = 1;
625 }
626
627 /* If someone thought that the redisplay was handled, but the currently
628 visible line has a different modification state than the one about
629 to become visible, then correct the caller's misconception. */
630 if (visible_line[0] != invisible_line[0])
631 rl_display_fixed = 0;
632
633 /* If the prompt to be displayed is the `primary' readline prompt (the
634 one passed to readline()), use the values we have already expanded.
635 If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
636 number of non-visible characters in the prompt string. */
637 if (rl_display_prompt == rl_prompt || local_prompt)
638 {
639 if (local_prompt_prefix && forced_display)
640 _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
641
642 if (local_prompt_len > 0)
643 {
644 temp = local_prompt_len + out + 2;
645 if (temp >= line_size)
646 {
647 line_size = (temp + 1024) - (temp % 1024);
648 visible_line = (char *)xrealloc (visible_line, line_size);
649 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
650 }
651 strncpy (line + out, local_prompt, local_prompt_len);
652 out += local_prompt_len;
653 }
654 line[out] = '\0';
655 wrap_offset = local_prompt_len - prompt_visible_length;
656 }
657 else
658 {
659 int pmtlen;
660 prompt_this_line = strrchr (rl_display_prompt, '\n');
661 if (!prompt_this_line)
662 prompt_this_line = rl_display_prompt;
663 else
664 {
665 prompt_this_line++;
666 pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
667 if (forced_display)
668 {
669 _rl_output_some_chars (rl_display_prompt, pmtlen);
670 /* Make sure we are at column zero even after a newline,
671 regardless of the state of terminal output processing. */
672 if (pmtlen < 2 || prompt_this_line[-2] != '\r')
673 cr ();
674 }
675 }
676
677 prompt_physical_chars = pmtlen = strlen (prompt_this_line);
678 temp = pmtlen + out + 2;
679 if (temp >= line_size)
680 {
681 line_size = (temp + 1024) - (temp % 1024);
682 visible_line = (char *)xrealloc (visible_line, line_size);
683 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
684 }
685 strncpy (line + out, prompt_this_line, pmtlen);
686 out += pmtlen;
687 line[out] = '\0';
688 wrap_offset = prompt_invis_chars_first_line = 0;
689 }
690
691#define CHECK_INV_LBREAKS() \
692 do { \
693 if (newlines >= (inv_lbsize - 2)) \
694 { \
695 inv_lbsize *= 2; \
696 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
697 } \
698 } while (0)
699
700#if defined (HANDLE_MULTIBYTE)
701#define CHECK_LPOS() \
702 do { \
703 lpos++; \
704 if (lpos >= _rl_screenwidth) \
705 { \
706 if (newlines >= (inv_lbsize - 2)) \
707 { \
708 inv_lbsize *= 2; \
709 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
710 } \
711 inv_lbreaks[++newlines] = out; \
712 if (newlines >= (line_state_invisible->wbsize - 1)) \
713 { \
714 line_state_invisible->wbsize *= 2; \
715 line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
716 } \
717 line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \
718 lpos = 0; \
719 } \
720 } while (0)
721#else
722#define CHECK_LPOS() \
723 do { \
724 lpos++; \
725 if (lpos >= _rl_screenwidth) \
726 { \
727 if (newlines >= (inv_lbsize - 2)) \
728 { \
729 inv_lbsize *= 2; \
730 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
731 } \
732 inv_lbreaks[++newlines] = out; \
733 lpos = 0; \
734 } \
735 } while (0)
736#endif
737
738 /* inv_lbreaks[i] is where line i starts in the buffer. */
739 inv_lbreaks[newlines = 0] = 0;
740 lpos = prompt_physical_chars + modmark;
741
742#if defined (HANDLE_MULTIBYTE)
743 memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
744 num = 0;
745#endif
746
747 /* prompt_invis_chars_first_line is the number of invisible characters in
748 the first physical line of the prompt.
749 wrap_offset - prompt_invis_chars_first_line is the number of invis
750 chars on the second (or, more generally, last) line. */
751
752 /* This is zero-based, used to set the newlines */
753 prompt_lines_estimate = lpos / _rl_screenwidth;
754
755 /* what if lpos is already >= _rl_screenwidth before we start drawing the
756 contents of the command line? */
757 while (lpos >= _rl_screenwidth)
758 {
759 int z, p;
760 /* fix from Darin Johnson <darin@acuson.com> for prompt string with
761 invisible characters that is longer than the screen width. The
762 prompt_invis_chars_first_line variable could be made into an array
763 saying how many invisible characters there are per line, but that's
764 probably too much work for the benefit gained. How many people have
765 prompts that exceed two physical lines?
766 Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
767#if defined (HANDLE_MULTIBYTE)
768 if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
769 {
770 n0 = num;
771 temp = local_prompt_len;
772 while (num < temp)
773 {
774 z = _rl_col_width (local_prompt, n0, num, 1);
775 if (z > _rl_screenwidth)
776 {
777 num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
778 break;
779 }
780 else if (z == _rl_screenwidth)
781 {
782 /* If we are in the middle or at the end of a multibyte
783 character, we want to move to the start, then find out
784 where it ends so we know where to insert the newline.
785 If this isn't a multibyte character, its the same as num++ */
786 p = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
787 num = _rl_find_next_mbchar (local_prompt, p, 1, MB_FIND_ANY);
788 break;
789 }
790 num++;
791 }
792 temp = num;
793 }
794 else
795#endif /* !HANDLE_MULTIBYTE */
796 temp = ((newlines + 1) * _rl_screenwidth);
797
798 /* Now account for invisible characters in the current line. */
799 /* XXX - this assumes that the invisible characters may be split, but only
800 between the first and the last lines. */
801 temp += (newlines == 0) ? prompt_invis_chars_first_line
802 : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line);
803
804 inv_lbreaks[++newlines] = temp;
805#if defined (HANDLE_MULTIBYTE)
806 if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
807 lpos -= _rl_col_width (local_prompt, n0, num, 1);
808 else
809#endif
810 lpos -= _rl_screenwidth;
811 }
812
813 prompt_last_screen_line = newlines;
814
815 /* Draw the rest of the line (after the prompt) into invisible_line, keeping
816 track of where the cursor is (cpos_buffer_position), the number of the line containing
817 the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
818 It maintains an array of line breaks for display (inv_lbreaks).
819 This handles expanding tabs for display and displaying meta characters. */
820 lb_linenum = 0;
821#if defined (HANDLE_MULTIBYTE)
822 in = 0;
823 if (mb_cur_max > 1 && rl_byte_oriented == 0)
824 {
825 memset (&ps, 0, sizeof (mbstate_t));
826 /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
827 wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
828 }
829 else
830 wc_bytes = 1;
831 while (in < rl_end)
832#else
833 for (in = 0; in < rl_end; in++)
834#endif
835 {
836 c = (unsigned char)rl_line_buffer[in];
837
838#if defined (HANDLE_MULTIBYTE)
839 if (mb_cur_max > 1 && rl_byte_oriented == 0)
840 {
841 if (MB_INVALIDCH (wc_bytes))
842 {
843 /* Byte sequence is invalid or shortened. Assume that the
844 first byte represents a character. */
845 wc_bytes = 1;
846 /* Assume that a character occupies a single column. */
847 wc_width = 1;
848 memset (&ps, 0, sizeof (mbstate_t));
849 }
850 else if (MB_NULLWCH (wc_bytes))
851 break; /* Found '\0' */
852 else
853 {
854 temp = WCWIDTH (wc);
855 wc_width = (temp >= 0) ? temp : 1;
856 }
857 }
858#endif
859
860 if (out + 8 >= line_size) /* XXX - 8 for \t */
861 {
862 line_size *= 2;
863 visible_line = (char *)xrealloc (visible_line, line_size);
864 invisible_line = (char *)xrealloc (invisible_line, line_size);
865 line = invisible_line;
866 }
867
868 if (in == rl_point)
869 {
870 cpos_buffer_position = out;
871 lb_linenum = newlines;
872 }
873
874#if defined (HANDLE_MULTIBYTE)
875 if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
876#else
877 if (META_CHAR (c))
878#endif
879 {
880 if (_rl_output_meta_chars == 0)
881 {
882 sprintf (line + out, "\\%o", c);
883
884 if (lpos + 4 >= _rl_screenwidth)
885 {
886 temp = _rl_screenwidth - lpos;
887 CHECK_INV_LBREAKS ();
888 inv_lbreaks[++newlines] = out + temp;
889 lpos = 4 - temp;
890 }
891 else
892 lpos += 4;
893
894 out += 4;
895 }
896 else
897 {
898 line[out++] = c;
899 CHECK_LPOS();
900 }
901 }
902#if defined (DISPLAY_TABS)
903 else if (c == '\t')
904 {
905 register int newout;
906
907#if 0
908 newout = (out | (int)7) + 1;
909#else
910 newout = out + 8 - lpos % 8;
911#endif
912 temp = newout - out;
913 if (lpos + temp >= _rl_screenwidth)
914 {
915 register int temp2;
916 temp2 = _rl_screenwidth - lpos;
917 CHECK_INV_LBREAKS ();
918 inv_lbreaks[++newlines] = out + temp2;
919 lpos = temp - temp2;
920 while (out < newout)
921 line[out++] = ' ';
922 }
923 else
924 {
925 while (out < newout)
926 line[out++] = ' ';
927 lpos += temp;
928 }
929 }
930#endif
931 else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
932 {
933 line[out++] = '\0'; /* XXX - sentinel */
934 CHECK_INV_LBREAKS ();
935 inv_lbreaks[++newlines] = out;
936 lpos = 0;
937 }
938 else if (CTRL_CHAR (c) || c == RUBOUT)
939 {
940 line[out++] = '^';
941 CHECK_LPOS();
942 line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
943 CHECK_LPOS();
944 }
945 else
946 {
947#if defined (HANDLE_MULTIBYTE)
948 if (mb_cur_max > 1 && rl_byte_oriented == 0)
949 {
950 register int i;
951
952 _rl_wrapped_multicolumn = 0;
953
954 if (_rl_screenwidth < lpos + wc_width)
955 for (i = lpos; i < _rl_screenwidth; i++)
956 {
957 /* The space will be removed in update_line() */
958 line[out++] = ' ';
959 _rl_wrapped_multicolumn++;
960 CHECK_LPOS();
961 }
962 if (in == rl_point)
963 {
964 cpos_buffer_position = out;
965 lb_linenum = newlines;
966 }
967 for (i = in; i < in+wc_bytes; i++)
968 line[out++] = rl_line_buffer[i];
969 for (i = 0; i < wc_width; i++)
970 CHECK_LPOS();
971 }
972 else
973 {
974 line[out++] = c;
975 CHECK_LPOS();
976 }
977#else
978 line[out++] = c;
979 CHECK_LPOS();
980#endif
981 }
982
983#if defined (HANDLE_MULTIBYTE)
984 if (mb_cur_max > 1 && rl_byte_oriented == 0)
985 {
986 in += wc_bytes;
987 /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
988 wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
989 }
990 else
991 in++;
992#endif
993
994 }
995 line[out] = '\0';
996 if (cpos_buffer_position < 0)
997 {
998 cpos_buffer_position = out;
999 lb_linenum = newlines;
1000 }
1001
1002 inv_botlin = lb_botlin = newlines;
1003 CHECK_INV_LBREAKS ();
1004 inv_lbreaks[newlines+1] = out;
1005 cursor_linenum = lb_linenum;
1006
1007 /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
1008 CURSOR_LINENUM == line number where the cursor should be placed. */
1009
1010 /* PWP: now is when things get a bit hairy. The visible and invisible
1011 line buffers are really multiple lines, which would wrap every
1012 (screenwidth - 1) characters. Go through each in turn, finding
1013 the changed region and updating it. The line order is top to bottom. */
1014
1015 /* If we can move the cursor up and down, then use multiple lines,
1016 otherwise, let long lines display in a single terminal line, and
1017 horizontally scroll it. */
1018 displaying_prompt_first_line = 1;
1019 if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
1020 {
1021 int nleft, pos, changed_screen_line, tx;
1022
1023 if (!rl_display_fixed || forced_display)
1024 {
1025 forced_display = 0;
1026
1027 /* If we have more than a screenful of material to display, then
1028 only display a screenful. We should display the last screen,
1029 not the first. */
1030 if (out >= _rl_screenchars)
1031 {
1032 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1033 out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
1034 else
1035 out = _rl_screenchars - 1;
1036 }
1037
1038 /* The first line is at character position 0 in the buffer. The
1039 second and subsequent lines start at inv_lbreaks[N], offset by
1040 OFFSET (which has already been calculated above). */
1041
1042#define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
1043#define WRAP_OFFSET(line, offset) ((line == 0) \
1044 ? (offset ? INVIS_FIRST() : 0) \
1045 : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
1046#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
1047#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
1048#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
1049#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
1050#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
1051#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
1052
1053#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
1054 _rl_last_c_pos != o_cpos && \
1055 _rl_last_c_pos > wrap_offset && \
1056 o_cpos < prompt_last_invisible)
1057
1058 /* For each line in the buffer, do the updating display. */
1059 for (linenum = 0; linenum <= inv_botlin; linenum++)
1060 {
1061 /* This can lead us astray if we execute a program that changes
1062 the locale from a non-multibyte to a multibyte one. */
1063 o_cpos = _rl_last_c_pos;
1064 cpos_adjusted = 0;
1065 update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
1066 VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
1067
1068 /* update_line potentially changes _rl_last_c_pos, but doesn't
1069 take invisible characters into account, since _rl_last_c_pos
1070 is an absolute cursor position in a multibyte locale. See
1071 if compensating here is the right thing, or if we have to
1072 change update_line itself. There are several cases in which
1073 update_line adjusts _rl_last_c_pos itself (so it can pass
1074 _rl_move_cursor_relative accurate values); it communicates
1075 this back by setting cpos_adjusted. If we assume that
1076 _rl_last_c_pos is correct (an absolute cursor position) each
1077 time update_line is called, then we can assume in our
1078 calculations that o_cpos does not need to be adjusted by
1079 wrap_offset. */
1080 if (linenum == 0 && (mb_cur_max > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
1081 _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
1082 else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
1083 (mb_cur_max > 1 && rl_byte_oriented == 0) &&
1084 cpos_adjusted == 0 &&
1085 _rl_last_c_pos != o_cpos &&
1086 _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
1087 _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
1088
1089 /* If this is the line with the prompt, we might need to
1090 compensate for invisible characters in the new line. Do
1091 this only if there is not more than one new line (which
1092 implies that we completely overwrite the old visible line)
1093 and the new line is shorter than the old. Make sure we are
1094 at the end of the new line before clearing. */
1095 if (linenum == 0 &&
1096 inv_botlin == 0 && _rl_last_c_pos == out &&
1097 (wrap_offset > visible_wrap_offset) &&
1098 (_rl_last_c_pos < visible_first_line_len))
1099 {
1100 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1101 nleft = _rl_screenwidth - _rl_last_c_pos;
1102 else
1103 nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
1104 if (nleft)
1105 _rl_clear_to_eol (nleft);
1106 }
1107#if 0
1108 /* This segment is intended to handle the case where the prompt
1109 has invisible characters on the second line and the new line
1110 to be displayed needs to clear the rest of the old characters
1111 out (e.g., when printing the i-search prompt). In general,
1112 the case of the new line being shorter than the old.
1113 Incomplete */
1114 else if (linenum == prompt_last_screen_line &&
1115 prompt_physical_chars > _rl_screenwidth &&
1116 wrap_offset != prompt_invis_chars_first_line &&
1117 _rl_last_c_pos == out &&
1118#endif
1119
1120
1121 /* Since the new first line is now visible, save its length. */
1122 if (linenum == 0)
1123 visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
1124 }
1125
1126 /* We may have deleted some lines. If so, clear the left over
1127 blank ones at the bottom out. */
1128 if (_rl_vis_botlin > inv_botlin)
1129 {
1130 char *tt;
1131 for (; linenum <= _rl_vis_botlin; linenum++)
1132 {
1133 tt = VIS_CHARS (linenum);
1134 _rl_move_vert (linenum);
1135 _rl_move_cursor_relative (0, tt);
1136 _rl_clear_to_eol
1137 ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
1138 }
1139 }
1140 _rl_vis_botlin = inv_botlin;
1141
1142 /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
1143 different screen line during this redisplay. */
1144 changed_screen_line = _rl_last_v_pos != cursor_linenum;
1145 if (changed_screen_line)
1146 {
1147 _rl_move_vert (cursor_linenum);
1148 /* If we moved up to the line with the prompt using _rl_term_up,
1149 the physical cursor position on the screen stays the same,
1150 but the buffer position needs to be adjusted to account
1151 for invisible characters. */
1152 if ((mb_cur_max == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
1153 _rl_last_c_pos += wrap_offset;
1154 }
1155
1156 /* We have to reprint the prompt if it contains invisible
1157 characters, since it's not generally OK to just reprint
1158 the characters from the current cursor position. But we
1159 only need to reprint it if the cursor is before the last
1160 invisible character in the prompt string. */
1161 nleft = prompt_visible_length + wrap_offset;
1162 if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
1163#if 0
1164 _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
1165#else
1166 _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
1167#endif
1168 {
1169#if defined (__MSDOS__)
1170 putc ('\r', rl_outstream);
1171#else
1172 if (_rl_term_cr)
1173 tputs (_rl_term_cr, 1, _rl_output_character_function);
1174#endif
1175 if (modmark)
1176 _rl_output_some_chars ("*", 1);
1177
1178 _rl_output_some_chars (local_prompt, nleft);
1179 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1180 _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
1181 else
1182 _rl_last_c_pos = nleft + modmark;
1183 }
1184
1185 /* Where on that line? And where does that line start
1186 in the buffer? */
1187 pos = inv_lbreaks[cursor_linenum];
1188 /* nleft == number of characters in the line buffer between the
1189 start of the line and the desired cursor position. */
1190 nleft = cpos_buffer_position - pos;
1191
1192 /* NLEFT is now a number of characters in a buffer. When in a
1193 multibyte locale, however, _rl_last_c_pos is an absolute cursor
1194 position that doesn't take invisible characters in the prompt
1195 into account. We use a fudge factor to compensate. */
1196
1197 /* Since _rl_backspace() doesn't know about invisible characters in the
1198 prompt, and there's no good way to tell it, we compensate for
1199 those characters here and call _rl_backspace() directly. */
1200 if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
1201 {
1202 /* TX == new physical cursor position in multibyte locale. */
1203 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1204 tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
1205 else
1206 tx = nleft;
1207 if (tx >= 0 && _rl_last_c_pos > tx)
1208 {
1209 _rl_backspace (_rl_last_c_pos - tx); /* XXX */
1210 _rl_last_c_pos = tx;
1211 }
1212 }
1213
1214 /* We need to note that in a multibyte locale we are dealing with
1215 _rl_last_c_pos as an absolute cursor position, but moving to a
1216 point specified by a buffer position (NLEFT) that doesn't take
1217 invisible characters into account. */
1218 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1219 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1220 else if (nleft != _rl_last_c_pos)
1221 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1222 }
1223 }
1224 else /* Do horizontal scrolling. */
1225 {
1226#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
1227 int lmargin, ndisp, nleft, phys_c_pos, t;
1228
1229 /* Always at top line. */
1230 _rl_last_v_pos = 0;
1231
1232 /* Compute where in the buffer the displayed line should start. This
1233 will be LMARGIN. */
1234
1235 /* The number of characters that will be displayed before the cursor. */
1236 ndisp = cpos_buffer_position - wrap_offset;
1237 nleft = prompt_visible_length + wrap_offset;
1238 /* Where the new cursor position will be on the screen. This can be
1239 longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
1240 phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
1241 t = _rl_screenwidth / 3;
1242
1243 /* If the number of characters had already exceeded the screenwidth,
1244 last_lmargin will be > 0. */
1245
1246 /* If the number of characters to be displayed is more than the screen
1247 width, compute the starting offset so that the cursor is about
1248 two-thirds of the way across the screen. */
1249 if (phys_c_pos > _rl_screenwidth - 2)
1250 {
1251 lmargin = cpos_buffer_position - (2 * t);
1252 if (lmargin < 0)
1253 lmargin = 0;
1254 /* If the left margin would be in the middle of a prompt with
1255 invisible characters, don't display the prompt at all. */
1256 if (wrap_offset && lmargin > 0 && lmargin < nleft)
1257 lmargin = nleft;
1258 }
1259 else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
1260 lmargin = 0;
1261 else if (phys_c_pos < 1)
1262 {
1263 /* If we are moving back towards the beginning of the line and
1264 the last margin is no longer correct, compute a new one. */
1265 lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */
1266 if (wrap_offset && lmargin > 0 && lmargin < nleft)
1267 lmargin = nleft;
1268 }
1269 else
1270 lmargin = last_lmargin;
1271
1272 displaying_prompt_first_line = lmargin < nleft;
1273
1274 /* If the first character on the screen isn't the first character
1275 in the display line, indicate this with a special character. */
1276 if (lmargin > 0)
1277 line[lmargin] = '<';
1278
1279 /* If SCREENWIDTH characters starting at LMARGIN do not encompass
1280 the whole line, indicate that with a special character at the
1281 right edge of the screen. If LMARGIN is 0, we need to take the
1282 wrap offset into account. */
1283 t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
1284 if (t < out)
1285 line[t - 1] = '>';
1286
1287 if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
1288 {
1289 forced_display = 0;
1290 o_cpos = _rl_last_c_pos;
1291 cpos_adjusted = 0;
1292 update_line (&visible_line[last_lmargin],
1293 &invisible_line[lmargin],
1294 0,
1295 _rl_screenwidth + visible_wrap_offset,
1296 _rl_screenwidth + (lmargin ? 0 : wrap_offset),
1297 0);
1298
1299 if ((mb_cur_max > 1 && rl_byte_oriented == 0) &&
1300 displaying_prompt_first_line && OLD_CPOS_IN_PROMPT())
1301 _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
1302
1303 /* If the visible new line is shorter than the old, but the number
1304 of invisible characters is greater, and we are at the end of
1305 the new line, we need to clear to eol. */
1306 t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
1307 if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
1308 (_rl_last_c_pos == out) && displaying_prompt_first_line &&
1309 t < visible_first_line_len)
1310 {
1311 nleft = _rl_screenwidth - t;
1312 _rl_clear_to_eol (nleft);
1313 }
1314 visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
1315 if (visible_first_line_len > _rl_screenwidth)
1316 visible_first_line_len = _rl_screenwidth;
1317
1318 _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
1319 last_lmargin = lmargin;
1320 }
1321 }
1322 fflush (rl_outstream);
1323
1324 /* Swap visible and non-visible lines. */
1325 {
1326 struct line_state *vtemp = line_state_visible;
1327
1328 line_state_visible = line_state_invisible;
1329 line_state_invisible = vtemp;
1330
1331 rl_display_fixed = 0;
1332 /* If we are displaying on a single line, and last_lmargin is > 0, we
1333 are not displaying any invisible characters, so set visible_wrap_offset
1334 to 0. */
1335 if (_rl_horizontal_scroll_mode && last_lmargin)
1336 visible_wrap_offset = 0;
1337 else
1338 visible_wrap_offset = wrap_offset;
1339 }
1340
1341 RL_UNSETSTATE (RL_STATE_REDISPLAYING);
1342 _rl_release_sigint ();
1343}
1344
1345/* PWP: update_line() is based on finding the middle difference of each
1346 line on the screen; vis:
1347
1348 /old first difference
1349 /beginning of line | /old last same /old EOL
1350 v v v v
1351old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
1352new: eddie> Oh, my little buggy says to me, as lurgid as
1353 ^ ^ ^ ^
1354 \beginning of line | \new last same \new end of line
1355 \new first difference
1356
1357 All are character pointers for the sake of speed. Special cases for
1358 no differences, as well as for end of line additions must be handled.
1359
1360 Could be made even smarter, but this works well enough */
1361static void
1362update_line (old, new, current_line, omax, nmax, inv_botlin)
1363 register char *old, *new;
1364 int current_line, omax, nmax, inv_botlin;
1365{
1366 register char *ofd, *ols, *oe, *nfd, *nls, *ne;
1367 int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
1368 int current_invis_chars;
1369 int col_lendiff, col_temp;
1370 int bytes_to_insert;
1371#if defined (HANDLE_MULTIBYTE)
1372 mbstate_t ps_new, ps_old;
1373 int new_offset, old_offset;
1374#endif
1375
1376 /* If we're at the right edge of a terminal that supports xn, we're
1377 ready to wrap around, so do so. This fixes problems with knowing
1378 the exact cursor position and cut-and-paste with certain terminal
1379 emulators. In this calculation, TEMP is the physical screen
1380 position of the cursor. */
1381 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1382 temp = _rl_last_c_pos;
1383 else
1384 temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
1385 if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
1386 && _rl_last_v_pos == current_line - 1)
1387 {
1388#if defined (HANDLE_MULTIBYTE)
1389 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1390 {
1391 wchar_t wc;
1392 mbstate_t ps;
1393 int tempwidth, bytes;
1394 size_t ret;
1395
1396 /* This fixes only double-column characters, but if the wrapped
1397 character consumes more than three columns, spaces will be
1398 inserted in the string buffer. */
1399 if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0)
1400 _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]);
1401
1402 memset (&ps, 0, sizeof (mbstate_t));
1403 ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
1404 if (MB_INVALIDCH (ret))
1405 {
1406 tempwidth = 1;
1407 ret = 1;
1408 }
1409 else if (MB_NULLWCH (ret))
1410 tempwidth = 0;
1411 else
1412 tempwidth = WCWIDTH (wc);
1413
1414 if (tempwidth > 0)
1415 {
1416 int count, i;
1417 bytes = ret;
1418 for (count = 0; count < bytes; count++)
1419 putc (new[count], rl_outstream);
1420 _rl_last_c_pos = tempwidth;
1421 _rl_last_v_pos++;
1422 memset (&ps, 0, sizeof (mbstate_t));
1423 ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
1424 if (ret != 0 && bytes != 0)
1425 {
1426 if (MB_INVALIDCH (ret))
1427 ret = 1;
1428 memmove (old+bytes, old+ret, strlen (old+ret));
1429 memcpy (old, new, bytes);
1430 /* Fix up indices if we copy data from one line to another */
1431 omax += bytes - ret;
1432 for (i = current_line+1; i <= inv_botlin+1; i++)
1433 vis_lbreaks[i] += bytes - ret;
1434 }
1435 }
1436 else
1437 {
1438 putc (' ', rl_outstream);
1439 _rl_last_c_pos = 1;
1440 _rl_last_v_pos++;
1441 if (old[0] && new[0])
1442 old[0] = new[0];
1443 }
1444 }
1445 else
1446#endif
1447 {
1448 if (new[0])
1449 putc (new[0], rl_outstream);
1450 else
1451 putc (' ', rl_outstream);
1452 _rl_last_c_pos = 1;
1453 _rl_last_v_pos++;
1454 if (old[0] && new[0])
1455 old[0] = new[0];
1456 }
1457 }
1458
1459
1460 /* Find first difference. */
1461#if defined (HANDLE_MULTIBYTE)
1462 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1463 {
1464 /* See if the old line is a subset of the new line, so that the
1465 only change is adding characters. */
1466 temp = (omax < nmax) ? omax : nmax;
1467 if (memcmp (old, new, temp) == 0) /* adding at the end */
1468 {
1469 new_offset = old_offset = temp;
1470 ofd = old + temp;
1471 nfd = new + temp;
1472 }
1473 else
1474 {
1475 memset (&ps_new, 0, sizeof(mbstate_t));
1476 memset (&ps_old, 0, sizeof(mbstate_t));
1477
1478 if (omax == nmax && STREQN (new, old, omax))
1479 {
1480 old_offset = omax;
1481 new_offset = nmax;
1482 ofd = old + omax;
1483 nfd = new + nmax;
1484 }
1485 else
1486 {
1487 new_offset = old_offset = 0;
1488 for (ofd = old, nfd = new;
1489 (ofd - old < omax) && *ofd &&
1490 _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
1491 {
1492 old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
1493 new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
1494
1495 ofd = old + old_offset;
1496 nfd = new + new_offset;
1497 }
1498 }
1499 }
1500 }
1501 else
1502#endif
1503 for (ofd = old, nfd = new;
1504 (ofd - old < omax) && *ofd && (*ofd == *nfd);
1505 ofd++, nfd++)
1506 ;
1507
1508 /* Move to the end of the screen line. ND and OD are used to keep track
1509 of the distance between ne and new and oe and old, respectively, to
1510 move a subtraction out of each loop. */
1511 for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
1512 for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
1513
1514 /* If no difference, continue to next line. */
1515 if (ofd == oe && nfd == ne)
1516 return;
1517
1518#if defined (HANDLE_MULTIBYTE)
1519 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_utf8locale)
1520 {
1521 wchar_t wc;
1522 mbstate_t ps = { 0 };
1523 int t;
1524
1525 /* If the first character in the difference is a zero-width character,
1526 assume it's a combining character and back one up so the two base
1527 characters no longer compare equivalently. */
1528 t = mbrtowc (&wc, ofd, MB_CUR_MAX, &ps);
1529 if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0)
1530 {
1531 old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY);
1532 new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY);
1533 ofd = old + old_offset; /* equal by definition */
1534 nfd = new + new_offset;
1535 }
1536 }
1537#endif
1538
1539 wsatend = 1; /* flag for trailing whitespace */
1540
1541#if defined (HANDLE_MULTIBYTE)
1542 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1543 {
1544 ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
1545 nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
1546
1547 while ((ols > ofd) && (nls > nfd))
1548 {
1549 memset (&ps_old, 0, sizeof (mbstate_t));
1550 memset (&ps_new, 0, sizeof (mbstate_t));
1551
1552#if 0
1553 /* On advice from jir@yamato.ibm.com */
1554 _rl_adjust_point (old, ols - old, &ps_old);
1555 _rl_adjust_point (new, nls - new, &ps_new);
1556#endif
1557
1558 if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
1559 break;
1560
1561 if (*ols == ' ')
1562 wsatend = 0;
1563
1564 ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
1565 nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
1566 }
1567 }
1568 else
1569 {
1570#endif /* HANDLE_MULTIBYTE */
1571 ols = oe - 1; /* find last same */
1572 nls = ne - 1;
1573 while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
1574 {
1575 if (*ols != ' ')
1576 wsatend = 0;
1577 ols--;
1578 nls--;
1579 }
1580#if defined (HANDLE_MULTIBYTE)
1581 }
1582#endif
1583
1584 if (wsatend)
1585 {
1586 ols = oe;
1587 nls = ne;
1588 }
1589#if defined (HANDLE_MULTIBYTE)
1590 /* This may not work for stateful encoding, but who cares? To handle
1591 stateful encoding properly, we have to scan each string from the
1592 beginning and compare. */
1593 else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
1594#else
1595 else if (*ols != *nls)
1596#endif
1597 {
1598 if (*ols) /* don't step past the NUL */
1599 {
1600 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1601 ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
1602 else
1603 ols++;
1604 }
1605 if (*nls)
1606 {
1607 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1608 nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
1609 else
1610 nls++;
1611 }
1612 }
1613
1614 /* count of invisible characters in the current invisible line. */
1615 current_invis_chars = W_OFFSET (current_line, wrap_offset);
1616 if (_rl_last_v_pos != current_line)
1617 {
1618 _rl_move_vert (current_line);
1619 if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
1620 _rl_last_c_pos += visible_wrap_offset;
1621 }
1622
1623 /* If this is the first line and there are invisible characters in the
1624 prompt string, and the prompt string has not changed, and the current
1625 cursor position is before the last invisible character in the prompt,
1626 and the index of the character to move to is past the end of the prompt
1627 string, then redraw the entire prompt string. We can only do this
1628 reliably if the terminal supports a `cr' capability.
1629
1630 This is not an efficiency hack -- there is a problem with redrawing
1631 portions of the prompt string if they contain terminal escape
1632 sequences (like drawing the `unbold' sequence without a corresponding
1633 `bold') that manifests itself on certain terminals. */
1634
1635 lendiff = local_prompt_len;
1636 od = ofd - old; /* index of first difference in visible line */
1637 if (current_line == 0 && !_rl_horizontal_scroll_mode &&
1638 _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
1639 od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
1640 {
1641#if defined (__MSDOS__)
1642 putc ('\r', rl_outstream);
1643#else
1644 tputs (_rl_term_cr, 1, _rl_output_character_function);
1645#endif
1646 if (modmark)
1647 _rl_output_some_chars ("*", 1);
1648 _rl_output_some_chars (local_prompt, lendiff);
1649 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1650 {
1651 /* We take wrap_offset into account here so we can pass correct
1652 information to _rl_move_cursor_relative. */
1653 _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
1654 cpos_adjusted = 1;
1655 }
1656 else
1657 _rl_last_c_pos = lendiff + modmark;
1658 }
1659
1660 o_cpos = _rl_last_c_pos;
1661
1662 /* When this function returns, _rl_last_c_pos is correct, and an absolute
1663 cursor position in multibyte mode, but a buffer index when not in a
1664 multibyte locale. */
1665 _rl_move_cursor_relative (od, old);
1666
1667#if defined (HANDLE_MULTIBYTE)
1668 /* We need to indicate that the cursor position is correct in the presence of
1669 invisible characters in the prompt string. Let's see if setting this when
1670 we make sure we're at the end of the drawn prompt string works. */
1671 if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
1672 (_rl_last_c_pos > 0 || o_cpos > 0) &&
1673 _rl_last_c_pos == prompt_physical_chars)
1674 cpos_adjusted = 1;
1675#endif
1676
1677 /* if (len (new) > len (old))
1678 lendiff == difference in buffer (bytes)
1679 col_lendiff == difference on screen (columns)
1680 When not using multibyte characters, these are equal */
1681 lendiff = (nls - nfd) - (ols - ofd);
1682 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1683 col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
1684 else
1685 col_lendiff = lendiff;
1686
1687 /* If we are changing the number of invisible characters in a line, and
1688 the spot of first difference is before the end of the invisible chars,
1689 lendiff needs to be adjusted. */
1690 if (current_line == 0 && /* !_rl_horizontal_scroll_mode && */
1691 current_invis_chars != visible_wrap_offset)
1692 {
1693 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1694 {
1695 lendiff += visible_wrap_offset - current_invis_chars;
1696 col_lendiff += visible_wrap_offset - current_invis_chars;
1697 }
1698 else
1699 {
1700 lendiff += visible_wrap_offset - current_invis_chars;
1701 col_lendiff = lendiff;
1702 }
1703 }
1704
1705 /* We use temp as a count of the number of bytes from the first difference
1706 to the end of the new line. col_temp is the corresponding number of
1707 screen columns. A `dumb' update moves to the spot of first difference
1708 and writes TEMP bytes. */
1709 /* Insert (diff (len (old), len (new)) ch. */
1710 temp = ne - nfd;
1711 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1712 col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
1713 else
1714 col_temp = temp;
1715
1716 /* how many bytes from the new line buffer to write to the display */
1717 bytes_to_insert = nls - nfd;
1718
1719 /* col_lendiff > 0 if we are adding characters to the line */
1720 if (col_lendiff > 0) /* XXX - was lendiff */
1721 {
1722 /* Non-zero if we're increasing the number of lines. */
1723 int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
1724 /* If col_lendiff is > 0, implying that the new string takes up more
1725 screen real estate than the old, but lendiff is < 0, meaning that it
1726 takes fewer bytes, we need to just output the characters starting
1727 from the first difference. These will overwrite what is on the
1728 display, so there's no reason to do a smart update. This can really
1729 only happen in a multibyte environment. */
1730 if (lendiff < 0)
1731 {
1732 _rl_output_some_chars (nfd, temp);
1733 _rl_last_c_pos += col_temp; /* XXX - was _rl_col_width (nfd, 0, temp, 1); */
1734 /* If nfd begins before any invisible characters in the prompt,
1735 adjust _rl_last_c_pos to account for wrap_offset and set
1736 cpos_adjusted to let the caller know. */
1737 if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
1738 {
1739 _rl_last_c_pos -= wrap_offset;
1740 cpos_adjusted = 1;
1741 }
1742 return;
1743 }
1744 /* Sometimes it is cheaper to print the characters rather than
1745 use the terminal's capabilities. If we're growing the number
1746 of lines, make sure we actually cause the new line to wrap
1747 around on auto-wrapping terminals. */
1748 else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
1749 {
1750 /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
1751 _rl_horizontal_scroll_mode == 1, inserting the characters with
1752 _rl_term_IC or _rl_term_ic will screw up the screen because of the
1753 invisible characters. We need to just draw them. */
1754 /* The same thing happens if we're trying to draw before the last
1755 invisible character in the prompt string or we're increasing the
1756 number of invisible characters in the line and we're not drawing
1757 the entire prompt string. */
1758 if (*ols && ((_rl_horizontal_scroll_mode &&
1759 _rl_last_c_pos == 0 &&
1760 lendiff > prompt_visible_length &&
1761 current_invis_chars > 0) == 0) &&
1762 (((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1763 current_line == 0 && wrap_offset &&
1764 ((nfd - new) <= prompt_last_invisible) &&
1765 (col_lendiff < prompt_visible_length)) == 0) &&
1766 (visible_wrap_offset >= current_invis_chars))
1767 {
1768 open_some_spaces (col_lendiff);
1769 _rl_output_some_chars (nfd, bytes_to_insert);
1770 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1771 _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
1772 else
1773 _rl_last_c_pos += bytes_to_insert;
1774 }
1775 else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
1776 {
1777 /* At the end of a line the characters do not have to
1778 be "inserted". They can just be placed on the screen. */
1779 _rl_output_some_chars (nfd, temp);
1780 _rl_last_c_pos += col_temp;
1781 return;
1782 }
1783 else /* just write from first difference to end of new line */
1784 {
1785 _rl_output_some_chars (nfd, temp);
1786 _rl_last_c_pos += col_temp;
1787 /* If nfd begins before the last invisible character in the
1788 prompt, adjust _rl_last_c_pos to account for wrap_offset
1789 and set cpos_adjusted to let the caller know. */
1790 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
1791 {
1792 _rl_last_c_pos -= wrap_offset;
1793 cpos_adjusted = 1;
1794 }
1795 return;
1796 }
1797
1798 if (bytes_to_insert > lendiff)
1799 {
1800 /* If nfd begins before the last invisible character in the
1801 prompt, adjust _rl_last_c_pos to account for wrap_offset
1802 and set cpos_adjusted to let the caller know. */
1803 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
1804 {
1805 _rl_last_c_pos -= wrap_offset;
1806 cpos_adjusted = 1;
1807 }
1808 }
1809 }
1810 else
1811 {
1812 /* cannot insert chars, write to EOL */
1813 _rl_output_some_chars (nfd, temp);
1814 _rl_last_c_pos += col_temp;
1815 /* If we're in a multibyte locale and were before the last invisible
1816 char in the current line (which implies we just output some invisible
1817 characters) we need to adjust _rl_last_c_pos, since it represents
1818 a physical character position. */
1819 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1820 current_line == prompt_last_screen_line && wrap_offset &&
1821 displaying_prompt_first_line &&
1822 wrap_offset != prompt_invis_chars_first_line &&
1823 ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
1824 {
1825 _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
1826 cpos_adjusted = 1;
1827 }
1828 }
1829 }
1830 else /* Delete characters from line. */
1831 {
1832 /* If possible and inexpensive to use terminal deletion, then do so. */
1833 if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
1834 {
1835 /* If all we're doing is erasing the invisible characters in the
1836 prompt string, don't bother. It screws up the assumptions
1837 about what's on the screen. */
1838 if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
1839 displaying_prompt_first_line &&
1840 -lendiff == visible_wrap_offset)
1841 col_lendiff = 0;
1842
1843 /* If we have moved lmargin and we're shrinking the line, we've
1844 already moved the cursor to the first character of the new line,
1845 so deleting -col_lendiff characters will mess up the cursor
1846 position calculation */
1847 if (_rl_horizontal_scroll_mode && displaying_prompt_first_line == 0 &&
1848 col_lendiff && _rl_last_c_pos < -col_lendiff)
1849 col_lendiff = 0;
1850
1851 if (col_lendiff)
1852 delete_chars (-col_lendiff); /* delete (diff) characters */
1853
1854 /* Copy (new) chars to screen from first diff to last match,
1855 overwriting what is there. */
1856 if (bytes_to_insert > 0)
1857 {
1858 /* If nfd begins at the prompt, or before the invisible
1859 characters in the prompt, we need to adjust _rl_last_c_pos
1860 in a multibyte locale to account for the wrap offset and
1861 set cpos_adjusted accordingly. */
1862 _rl_output_some_chars (nfd, bytes_to_insert);
1863 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1864 {
1865 _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
1866 if (current_line == 0 && wrap_offset &&
1867 displaying_prompt_first_line &&
1868 _rl_last_c_pos > wrap_offset &&
1869 ((nfd - new) <= prompt_last_invisible))
1870 {
1871 _rl_last_c_pos -= wrap_offset;
1872 cpos_adjusted = 1;
1873 }
1874 }
1875 else
1876 _rl_last_c_pos += bytes_to_insert;
1877
1878 /* XXX - we only want to do this if we are at the end of the line
1879 so we move there with _rl_move_cursor_relative */
1880 if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new)))
1881 {
1882 _rl_move_cursor_relative (ne-new, new);
1883 goto clear_rest_of_line;
1884 }
1885 }
1886 }
1887 /* Otherwise, print over the existing material. */
1888 else
1889 {
1890 if (temp > 0)
1891 {
1892 /* If nfd begins at the prompt, or before the invisible
1893 characters in the prompt, we need to adjust _rl_last_c_pos
1894 in a multibyte locale to account for the wrap offset and
1895 set cpos_adjusted accordingly. */
1896 _rl_output_some_chars (nfd, temp);
1897 _rl_last_c_pos += col_temp; /* XXX */
1898 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1899 {
1900 if (current_line == 0 && wrap_offset &&
1901 displaying_prompt_first_line &&
1902 _rl_last_c_pos > wrap_offset &&
1903 ((nfd - new) <= prompt_last_invisible))
1904 {
1905 _rl_last_c_pos -= wrap_offset;
1906 cpos_adjusted = 1;
1907 }
1908 }
1909 }
1910clear_rest_of_line:
1911 lendiff = (oe - old) - (ne - new);
1912 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1913 col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
1914 else
1915 col_lendiff = lendiff;
1916
1917 /* If we've already printed over the entire width of the screen,
1918 including the old material, then col_lendiff doesn't matter and
1919 space_to_eol will insert too many spaces. XXX - maybe we should
1920 adjust col_lendiff based on the difference between _rl_last_c_pos
1921 and _rl_screenwidth */
1922 if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
1923 {
1924 if (_rl_term_autowrap && current_line < inv_botlin)
1925 space_to_eol (col_lendiff);
1926 else
1927 _rl_clear_to_eol (col_lendiff);
1928 }
1929 }
1930 }
1931}
1932
1933/* Tell the update routines that we have moved onto a new (empty) line. */
1934int
1935rl_on_new_line ()
1936{
1937 if (visible_line)
1938 visible_line[0] = '\0';
1939
1940 _rl_last_c_pos = _rl_last_v_pos = 0;
1941 _rl_vis_botlin = last_lmargin = 0;
1942 if (vis_lbreaks)
1943 vis_lbreaks[0] = vis_lbreaks[1] = 0;
1944 visible_wrap_offset = 0;
1945 return 0;
1946}
1947
1948/* Tell the update routines that we have moved onto a new line with the
1949 prompt already displayed. Code originally from the version of readline
1950 distributed with CLISP. rl_expand_prompt must have already been called
1951 (explicitly or implicitly). This still doesn't work exactly right. */
1952int
1953rl_on_new_line_with_prompt ()
1954{
1955 int prompt_size, i, l, real_screenwidth, newlines;
1956 char *prompt_last_line, *lprompt;
1957
1958 /* Initialize visible_line and invisible_line to ensure that they can hold
1959 the already-displayed prompt. */
1960 prompt_size = strlen (rl_prompt) + 1;
1961 init_line_structures (prompt_size);
1962
1963 /* Make sure the line structures hold the already-displayed prompt for
1964 redisplay. */
1965 lprompt = local_prompt ? local_prompt : rl_prompt;
1966 strcpy (visible_line, lprompt);
1967 strcpy (invisible_line, lprompt);
1968
1969 /* If the prompt contains newlines, take the last tail. */
1970 prompt_last_line = strrchr (rl_prompt, '\n');
1971 if (!prompt_last_line)
1972 prompt_last_line = rl_prompt;
1973
1974 l = strlen (prompt_last_line);
1975 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1976 _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1); /* XXX */
1977 else
1978 _rl_last_c_pos = l;
1979
1980 /* Dissect prompt_last_line into screen lines. Note that here we have
1981 to use the real screenwidth. Readline's notion of screenwidth might be
1982 one less, see terminal.c. */
1983 real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
1984 _rl_last_v_pos = l / real_screenwidth;
1985 /* If the prompt length is a multiple of real_screenwidth, we don't know
1986 whether the cursor is at the end of the last line, or already at the
1987 beginning of the next line. Output a newline just to be safe. */
1988 if (l > 0 && (l % real_screenwidth) == 0)
1989 _rl_output_some_chars ("\n", 1);
1990 last_lmargin = 0;
1991
1992 newlines = 0; i = 0;
1993 while (i <= l)
1994 {
1995 _rl_vis_botlin = newlines;
1996 vis_lbreaks[newlines++] = i;
1997 i += real_screenwidth;
1998 }
1999 vis_lbreaks[newlines] = l;
2000 visible_wrap_offset = 0;
2001
2002 rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
2003
2004 return 0;
2005}
2006
2007/* Actually update the display, period. */
2008int
2009rl_forced_update_display ()
2010{
2011 register char *temp;
2012
2013 if (visible_line)
2014 {
2015 temp = visible_line;
2016 while (*temp)
2017 *temp++ = '\0';
2018 }
2019 rl_on_new_line ();
2020 forced_display++;
2021 (*rl_redisplay_function) ();
2022 return 0;
2023}
2024
2025/* Redraw only the last line of a multi-line prompt. */
2026void
2027rl_redraw_prompt_last_line ()
2028{
2029 char *t;
2030
2031 t = strrchr (rl_display_prompt, '\n');
2032 if (t)
2033 redraw_prompt (++t);
2034 else
2035 rl_forced_update_display ();
2036}
2037
2038/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
2039 (Well, when we don't have multibyte characters, _rl_last_c_pos is a
2040 buffer index.)
2041 DATA is the contents of the screen line of interest; i.e., where
2042 the movement is being done. */
2043void
2044_rl_move_cursor_relative (new, data)
2045 int new;
2046 const char *data;
2047{
2048 register int i;
2049 int woff; /* number of invisible chars on current line */
2050 int cpos, dpos; /* current and desired cursor positions */
2051 int adjust;
2052
2053 woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
2054 cpos = _rl_last_c_pos;
2055
2056 if (cpos == 0 && cpos == new)
2057 return;
2058
2059#if defined (HANDLE_MULTIBYTE)
2060 /* If we have multibyte characters, NEW is indexed by the buffer point in
2061 a multibyte string, but _rl_last_c_pos is the display position. In
2062 this case, NEW's display position is not obvious and must be
2063 calculated. We need to account for invisible characters in this line,
2064 as long as we are past them and they are counted by _rl_col_width. */
2065 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2066 {
2067 adjust = 1;
2068 /* Try to short-circuit common cases and eliminate a bunch of multibyte
2069 character function calls. */
2070 /* 1. prompt string */
2071 if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
2072 {
2073 dpos = prompt_physical_chars;
2074 cpos_adjusted = 1;
2075 adjust = 0;
2076 }
2077 /* 2. prompt_string + line contents */
2078 else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0)
2079 {
2080 dpos = prompt_physical_chars + _rl_col_width (data, local_prompt_len, new, 1);
2081 cpos_adjusted = 1;
2082 adjust = 0;
2083 }
2084 else
2085 dpos = _rl_col_width (data, 0, new, 1);
2086
2087 if (displaying_prompt_first_line == 0)
2088 adjust = 0;
2089
2090 /* Use NEW when comparing against the last invisible character in the
2091 prompt string, since they're both buffer indices and DPOS is a
2092 desired display position. */
2093 if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */
2094 (prompt_physical_chars >= _rl_screenwidth &&
2095 _rl_last_v_pos == prompt_last_screen_line &&
2096 wrap_offset >= woff && dpos >= woff &&
2097 new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
2098 /* XXX last comparison might need to be >= */
2099 {
2100 dpos -= woff;
2101 /* Since this will be assigned to _rl_last_c_pos at the end (more
2102 precisely, _rl_last_c_pos == dpos when this function returns),
2103 let the caller know. */
2104 cpos_adjusted = 1;
2105 }
2106 }
2107 else
2108#endif
2109 dpos = new;
2110
2111 /* If we don't have to do anything, then return. */
2112 if (cpos == dpos)
2113 return;
2114
2115 /* It may be faster to output a CR, and then move forwards instead
2116 of moving backwards. */
2117 /* i == current physical cursor position. */
2118#if defined (HANDLE_MULTIBYTE)
2119 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2120 i = _rl_last_c_pos;
2121 else
2122#endif
2123 i = _rl_last_c_pos - woff;
2124 if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
2125 (_rl_term_autowrap && i == _rl_screenwidth))
2126 {
2127#if defined (__MSDOS__)
2128 putc ('\r', rl_outstream);
2129#else
2130 tputs (_rl_term_cr, 1, _rl_output_character_function);
2131#endif /* !__MSDOS__ */
2132 cpos = _rl_last_c_pos = 0;
2133 }
2134
2135 if (cpos < dpos)
2136 {
2137 /* Move the cursor forward. We do it by printing the command
2138 to move the cursor forward if there is one, else print that
2139 portion of the output buffer again. Which is cheaper? */
2140
2141 /* The above comment is left here for posterity. It is faster
2142 to print one character (non-control) than to print a control
2143 sequence telling the terminal to move forward one character.
2144 That kind of control is for people who don't know what the
2145 data is underneath the cursor. */
2146
2147 /* However, we need a handle on where the current display position is
2148 in the buffer for the immediately preceding comment to be true.
2149 In multibyte locales, we don't currently have that info available.
2150 Without it, we don't know where the data we have to display begins
2151 in the buffer and we have to go back to the beginning of the screen
2152 line. In this case, we can use the terminal sequence to move forward
2153 if it's available. */
2154 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2155 {
2156 if (_rl_term_forward_char)
2157 {
2158 for (i = cpos; i < dpos; i++)
2159 tputs (_rl_term_forward_char, 1, _rl_output_character_function);
2160 }
2161 else
2162 {
2163 tputs (_rl_term_cr, 1, _rl_output_character_function);
2164 for (i = 0; i < new; i++)
2165 putc (data[i], rl_outstream);
2166 }
2167 }
2168 else
2169 for (i = cpos; i < new; i++)
2170 putc (data[i], rl_outstream);
2171 }
2172
2173#if defined (HANDLE_MULTIBYTE)
2174 /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
2175 The byte length of the string is probably bigger than the column width
2176 of the string, which means that if NEW == _rl_last_c_pos, then NEW's
2177 display point is less than _rl_last_c_pos. */
2178#endif
2179 else if (cpos > dpos)
2180 _rl_backspace (cpos - dpos);
2181
2182 _rl_last_c_pos = dpos;
2183}
2184
2185/* PWP: move the cursor up or down. */
2186void
2187_rl_move_vert (to)
2188 int to;
2189{
2190 register int delta, i;
2191
2192 if (_rl_last_v_pos == to || to > _rl_screenheight)
2193 return;
2194
2195 if ((delta = to - _rl_last_v_pos) > 0)
2196 {
2197 for (i = 0; i < delta; i++)
2198 putc ('\n', rl_outstream);
2199#if defined (__MSDOS__)
2200 putc ('\r', rl_outstream);
2201#else
2202 tputs (_rl_term_cr, 1, _rl_output_character_function);
2203#endif
2204 _rl_last_c_pos = 0;
2205 }
2206 else
2207 { /* delta < 0 */
2208#ifdef __DJGPP__
2209 int row, col;
2210
2211 fflush (rl_outstream);
2212 ScreenGetCursor (&row, &col);
2213 ScreenSetCursor (row + delta, col);
2214 i = -delta;
2215#else
2216 if (_rl_term_up && *_rl_term_up)
2217 for (i = 0; i < -delta; i++)
2218 tputs (_rl_term_up, 1, _rl_output_character_function);
2219#endif /* !__DJGPP__ */
2220 }
2221
2222 _rl_last_v_pos = to; /* Now TO is here */
2223}
2224
2225/* Physically print C on rl_outstream. This is for functions which know
2226 how to optimize the display. Return the number of characters output. */
2227int
2228rl_show_char (c)
2229 int c;
2230{
2231 int n = 1;
2232 if (META_CHAR (c) && (_rl_output_meta_chars == 0))
2233 {
2234 fprintf (rl_outstream, "M-");
2235 n += 2;
2236 c = UNMETA (c);
2237 }
2238
2239#if defined (DISPLAY_TABS)
2240 if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
2241#else
2242 if (CTRL_CHAR (c) || c == RUBOUT)
2243#endif /* !DISPLAY_TABS */
2244 {
2245 fprintf (rl_outstream, "C-");
2246 n += 2;
2247 c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
2248 }
2249
2250 putc (c, rl_outstream);
2251 fflush (rl_outstream);
2252 return n;
2253}
2254
2255int
2256rl_character_len (c, pos)
2257 register int c, pos;
2258{
2259 unsigned char uc;
2260
2261 uc = (unsigned char)c;
2262
2263 if (META_CHAR (uc))
2264 return ((_rl_output_meta_chars == 0) ? 4 : 1);
2265
2266 if (uc == '\t')
2267 {
2268#if defined (DISPLAY_TABS)
2269 return (((pos | 7) + 1) - pos);
2270#else
2271 return (2);
2272#endif /* !DISPLAY_TABS */
2273 }
2274
2275 if (CTRL_CHAR (c) || c == RUBOUT)
2276 return (2);
2277
2278 return ((ISPRINT (uc)) ? 1 : 2);
2279}
2280/* How to print things in the "echo-area". The prompt is treated as a
2281 mini-modeline. */
2282static int msg_saved_prompt = 0;
2283
2284#if defined (USE_VARARGS)
2285int
2286#if defined (PREFER_STDARG)
2287rl_message (const char *format, ...)
2288#else
2289rl_message (va_alist)
2290 va_dcl
2291#endif
2292{
2293 va_list args;
2294#if defined (PREFER_VARARGS)
2295 char *format;
2296#endif
2297#if defined (HAVE_VSNPRINTF)
2298 int bneed;
2299#endif
2300
2301#if defined (PREFER_STDARG)
2302 va_start (args, format);
2303#else
2304 va_start (args);
2305 format = va_arg (args, char *);
2306#endif
2307
2308 if (msg_buf == 0)
2309 msg_buf = xmalloc (msg_bufsiz = 128);
2310
2311#if defined (HAVE_VSNPRINTF)
2312 bneed = vsnprintf (msg_buf, msg_bufsiz, format, args);
2313 if (bneed >= msg_bufsiz - 1)
2314 {
2315 msg_bufsiz = bneed + 1;
2316 msg_buf = xrealloc (msg_buf, msg_bufsiz);
2317 va_end (args);
2318
2319#if defined (PREFER_STDARG)
2320 va_start (args, format);
2321#else
2322 va_start (args);
2323 format = va_arg (args, char *);
2324#endif
2325 vsnprintf (msg_buf, msg_bufsiz - 1, format, args);
2326 }
2327#else
2328 vsprintf (msg_buf, format, args);
2329 msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */
2330#endif
2331 va_end (args);
2332
2333 if (saved_local_prompt == 0)
2334 {
2335 rl_save_prompt ();
2336 msg_saved_prompt = 1;
2337 }
2338 else if (local_prompt != saved_local_prompt)
2339 {
2340 FREE (local_prompt);
2341 FREE (local_prompt_prefix);
2342 local_prompt = (char *)NULL;
2343 }
2344 rl_display_prompt = msg_buf;
2345 local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
2346 &prompt_last_invisible,
2347 &prompt_invis_chars_first_line,
2348 &prompt_physical_chars);
2349 local_prompt_prefix = (char *)NULL;
2350 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
2351 (*rl_redisplay_function) ();
2352
2353 return 0;
2354}
2355#else /* !USE_VARARGS */
2356int
2357rl_message (format, arg1, arg2)
2358 char *format;
2359{
2360 if (msg_buf == 0)
2361 msg_buf = xmalloc (msg_bufsiz = 128);
2362
2363 sprintf (msg_buf, format, arg1, arg2);
2364 msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */
2365
2366 rl_display_prompt = msg_buf;
2367 if (saved_local_prompt == 0)
2368 {
2369 rl_save_prompt ();
2370 msg_saved_prompt = 1;
2371 }
2372 else if (local_prompt != saved_local_prompt)
2373 {
2374 FREE (local_prompt);
2375 FREE (local_prompt_prefix);
2376 local_prompt = (char *)NULL;
2377 }
2378 local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
2379 &prompt_last_invisible,
2380 &prompt_invis_chars_first_line,
2381 &prompt_physical_chars);
2382 local_prompt_prefix = (char *)NULL;
2383 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
2384 (*rl_redisplay_function) ();
2385
2386 return 0;
2387}
2388#endif /* !USE_VARARGS */
2389
2390/* How to clear things from the "echo-area". */
2391int
2392rl_clear_message ()
2393{
2394 rl_display_prompt = rl_prompt;
2395 if (msg_saved_prompt)
2396 {
2397 rl_restore_prompt ();
2398 msg_saved_prompt = 0;
2399 }
2400 (*rl_redisplay_function) ();
2401 return 0;
2402}
2403
2404int
2405rl_reset_line_state ()
2406{
2407 rl_on_new_line ();
2408
2409 rl_display_prompt = rl_prompt ? rl_prompt : "";
2410 forced_display = 1;
2411 return 0;
2412}
2413
2414void
2415rl_save_prompt ()
2416{
2417 saved_local_prompt = local_prompt;
2418 saved_local_prefix = local_prompt_prefix;
2419 saved_prefix_length = prompt_prefix_length;
2420 saved_local_length = local_prompt_len;
2421 saved_last_invisible = prompt_last_invisible;
2422 saved_visible_length = prompt_visible_length;
2423 saved_invis_chars_first_line = prompt_invis_chars_first_line;
2424 saved_physical_chars = prompt_physical_chars;
2425
2426 local_prompt = local_prompt_prefix = (char *)0;
2427 local_prompt_len = 0;
2428 prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
2429 prompt_invis_chars_first_line = prompt_physical_chars = 0;
2430}
2431
2432void
2433rl_restore_prompt ()
2434{
2435 FREE (local_prompt);
2436 FREE (local_prompt_prefix);
2437
2438 local_prompt = saved_local_prompt;
2439 local_prompt_prefix = saved_local_prefix;
2440 local_prompt_len = saved_local_length;
2441 prompt_prefix_length = saved_prefix_length;
2442 prompt_last_invisible = saved_last_invisible;
2443 prompt_visible_length = saved_visible_length;
2444 prompt_invis_chars_first_line = saved_invis_chars_first_line;
2445 prompt_physical_chars = saved_physical_chars;
2446
2447 /* can test saved_local_prompt to see if prompt info has been saved. */
2448 saved_local_prompt = saved_local_prefix = (char *)0;
2449 saved_local_length = 0;
2450 saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
2451 saved_invis_chars_first_line = saved_physical_chars = 0;
2452}
2453
2454char *
2455_rl_make_prompt_for_search (pchar)
2456 int pchar;
2457{
2458 int len;
2459 char *pmt, *p;
2460
2461 rl_save_prompt ();
2462
2463 /* We've saved the prompt, and can do anything with the various prompt
2464 strings we need before they're restored. We want the unexpanded
2465 portion of the prompt string after any final newline. */
2466 p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
2467 if (p == 0)
2468 {
2469 len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
2470 pmt = (char *)xmalloc (len + 2);
2471 if (len)
2472 strcpy (pmt, rl_prompt);
2473 pmt[len] = pchar;
2474 pmt[len+1] = '\0';
2475 }
2476 else
2477 {
2478 p++;
2479 len = strlen (p);
2480 pmt = (char *)xmalloc (len + 2);
2481 if (len)
2482 strcpy (pmt, p);
2483 pmt[len] = pchar;
2484 pmt[len+1] = '\0';
2485 }
2486
2487 /* will be overwritten by expand_prompt, called from rl_message */
2488 prompt_physical_chars = saved_physical_chars + 1;
2489 return pmt;
2490}
2491
2492/* Quick redisplay hack when erasing characters at the end of the line. */
2493void
2494_rl_erase_at_end_of_line (l)
2495 int l;
2496{
2497 register int i;
2498
2499 _rl_backspace (l);
2500 for (i = 0; i < l; i++)
2501 putc (' ', rl_outstream);
2502 _rl_backspace (l);
2503 for (i = 0; i < l; i++)
2504 visible_line[--_rl_last_c_pos] = '\0';
2505 rl_display_fixed++;
2506}
2507
2508/* Clear to the end of the line. COUNT is the minimum
2509 number of character spaces to clear, */
2510void
2511_rl_clear_to_eol (count)
2512 int count;
2513{
2514#ifndef __MSDOS__
2515 if (_rl_term_clreol)
2516 tputs (_rl_term_clreol, 1, _rl_output_character_function);
2517 else
2518#endif
2519 if (count)
2520 space_to_eol (count);
2521}
2522
2523/* Clear to the end of the line using spaces. COUNT is the minimum
2524 number of character spaces to clear, */
2525static void
2526space_to_eol (count)
2527 int count;
2528{
2529 register int i;
2530
2531 for (i = 0; i < count; i++)
2532 putc (' ', rl_outstream);
2533
2534 _rl_last_c_pos += count;
2535}
2536
2537void
2538_rl_clear_screen ()
2539{
2540#ifndef __DJGPP__
2541 if (_rl_term_clrpag)
2542 tputs (_rl_term_clrpag, 1, _rl_output_character_function);
2543 else
2544 rl_crlf ();
2545#else
2546 ScreenClear ();
2547 ScreenSetCursor (0, 0);
2548#endif /* __DJGPP__ */
2549}
2550
2551/* Insert COUNT characters from STRING to the output stream at column COL. */
2552static void
2553insert_some_chars (string, count, col)
2554 char *string;
2555 int count, col;
2556{
2557 open_some_spaces (col);
2558 _rl_output_some_chars (string, count);
2559}
2560
2561/* Insert COL spaces, keeping the cursor at the same position. We follow the
2562 ncurses documentation and use either im/ei with explicit spaces, or IC/ic
2563 by itself. We assume there will either be ei or we don't need to use it. */
2564static void
2565open_some_spaces (col)
2566 int col;
2567{
2568#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
2569 char *buffer;
2570 register int i;
2571
2572 /* If IC is defined, then we do not have to "enter" insert mode. */
2573 if (_rl_term_IC)
2574 {
2575 buffer = tgoto (_rl_term_IC, 0, col);
2576 tputs (buffer, 1, _rl_output_character_function);
2577 }
2578 else if (_rl_term_im && *_rl_term_im)
2579 {
2580 tputs (_rl_term_im, 1, _rl_output_character_function);
2581 /* just output the desired number of spaces */
2582 for (i = col; i--; )
2583 _rl_output_character_function (' ');
2584 /* If there is a string to turn off insert mode, use it now. */
2585 if (_rl_term_ei && *_rl_term_ei)
2586 tputs (_rl_term_ei, 1, _rl_output_character_function);
2587 /* and move back the right number of spaces */
2588 _rl_backspace (col);
2589 }
2590 else if (_rl_term_ic && *_rl_term_ic)
2591 {
2592 /* If there is a special command for inserting characters, then
2593 use that first to open up the space. */
2594 for (i = col; i--; )
2595 tputs (_rl_term_ic, 1, _rl_output_character_function);
2596 }
2597#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
2598}
2599
2600/* Delete COUNT characters from the display line. */
2601static void
2602delete_chars (count)
2603 int count;
2604{
2605 if (count > _rl_screenwidth) /* XXX */
2606 return;
2607
2608#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
2609 if (_rl_term_DC && *_rl_term_DC)
2610 {
2611 char *buffer;
2612 buffer = tgoto (_rl_term_DC, count, count);
2613 tputs (buffer, count, _rl_output_character_function);
2614 }
2615 else
2616 {
2617 if (_rl_term_dc && *_rl_term_dc)
2618 while (count--)
2619 tputs (_rl_term_dc, 1, _rl_output_character_function);
2620 }
2621#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
2622}
2623
2624void
2625_rl_update_final ()
2626{
2627 int full_lines;
2628
2629 full_lines = 0;
2630 /* If the cursor is the only thing on an otherwise-blank last line,
2631 compensate so we don't print an extra CRLF. */
2632 if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
2633 visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
2634 {
2635 _rl_vis_botlin--;
2636 full_lines = 1;
2637 }
2638 _rl_move_vert (_rl_vis_botlin);
2639 /* If we've wrapped lines, remove the final xterm line-wrap flag. */
2640 if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
2641 {
2642 char *last_line;
2643
2644 last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
2645 cpos_buffer_position = -1; /* don't know where we are in buffer */
2646 _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */
2647 _rl_clear_to_eol (0);
2648 putc (last_line[_rl_screenwidth - 1], rl_outstream);
2649 }
2650 _rl_vis_botlin = 0;
2651 rl_crlf ();
2652 fflush (rl_outstream);
2653 rl_display_fixed++;
2654}
2655
2656/* Move to the start of the current line. */
2657static void
2658cr ()
2659{
2660 if (_rl_term_cr)
2661 {
2662#if defined (__MSDOS__)
2663 putc ('\r', rl_outstream);
2664#else
2665 tputs (_rl_term_cr, 1, _rl_output_character_function);
2666#endif
2667 _rl_last_c_pos = 0;
2668 }
2669}
2670
2671/* Redraw the last line of a multi-line prompt that may possibly contain
2672 terminal escape sequences. Called with the cursor at column 0 of the
2673 line to draw the prompt on. */
2674static void
2675redraw_prompt (t)
2676 char *t;
2677{
2678 char *oldp;
2679
2680 oldp = rl_display_prompt;
2681 rl_save_prompt ();
2682
2683 rl_display_prompt = t;
2684 local_prompt = expand_prompt (t, PMT_MULTILINE,
2685 &prompt_visible_length,
2686 &prompt_last_invisible,
2687 &prompt_invis_chars_first_line,
2688 &prompt_physical_chars);
2689 local_prompt_prefix = (char *)NULL;
2690 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
2691
2692 rl_forced_update_display ();
2693
2694 rl_display_prompt = oldp;
2695 rl_restore_prompt();
2696}
2697
2698/* Redisplay the current line after a SIGWINCH is received. */
2699void
2700_rl_redisplay_after_sigwinch ()
2701{
2702 char *t;
2703
2704 /* Clear the last line (assuming that the screen size change will result in
2705 either more or fewer characters on that line only) and put the cursor at
2706 column 0. Make sure the right thing happens if we have wrapped to a new
2707 screen line. */
2708 if (_rl_term_cr)
2709 {
2710 _rl_move_vert (_rl_vis_botlin);
2711
2712#if defined (__MSDOS__)
2713 putc ('\r', rl_outstream);
2714#else
2715 tputs (_rl_term_cr, 1, _rl_output_character_function);
2716#endif
2717 _rl_last_c_pos = 0;
2718#if defined (__MSDOS__)
2719 space_to_eol (_rl_screenwidth);
2720 putc ('\r', rl_outstream);
2721#else
2722 if (_rl_term_clreol)
2723 tputs (_rl_term_clreol, 1, _rl_output_character_function);
2724 else
2725 {
2726 space_to_eol (_rl_screenwidth);
2727 tputs (_rl_term_cr, 1, _rl_output_character_function);
2728 }
2729#endif
2730 if (_rl_last_v_pos > 0)
2731 _rl_move_vert (0);
2732 }
2733 else
2734 rl_crlf ();
2735
2736 /* Redraw only the last line of a multi-line prompt. */
2737 t = strrchr (rl_display_prompt, '\n');
2738 if (t)
2739 redraw_prompt (++t);
2740 else
2741 rl_forced_update_display ();
2742}
2743
2744void
2745_rl_clean_up_for_exit ()
2746{
2747 if (_rl_echoing_p)
2748 {
2749 if (_rl_vis_botlin > 0) /* minor optimization plus bug fix */
2750 _rl_move_vert (_rl_vis_botlin);
2751 _rl_vis_botlin = 0;
2752 fflush (rl_outstream);
2753 rl_restart_output (1, 0);
2754 }
2755}
2756
2757void
2758_rl_erase_entire_line ()
2759{
2760 cr ();
2761 _rl_clear_to_eol (0);
2762 cr ();
2763 fflush (rl_outstream);
2764}
2765
2766void
2767_rl_ttyflush ()
2768{
2769 fflush (rl_outstream);
2770}
2771
2772/* return the `current display line' of the cursor -- the number of lines to
2773 move up to get to the first screen line of the current readline line. */
2774int
2775_rl_current_display_line ()
2776{
2777 int ret, nleft;
2778
2779 /* Find out whether or not there might be invisible characters in the
2780 editing buffer. */
2781 if (rl_display_prompt == rl_prompt)
2782 nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
2783 else
2784 nleft = _rl_last_c_pos - _rl_screenwidth;
2785
2786 if (nleft > 0)
2787 ret = 1 + nleft / _rl_screenwidth;
2788 else
2789 ret = 0;
2790
2791 return ret;
2792}
2793
2794#if defined (HANDLE_MULTIBYTE)
2795/* Calculate the number of screen columns occupied by STR from START to END.
2796 In the case of multibyte characters with stateful encoding, we have to
2797 scan from the beginning of the string to take the state into account. */
2798static int
2799_rl_col_width (str, start, end, flags)
2800 const char *str;
2801 int start, end, flags;
2802{
2803 wchar_t wc;
2804 mbstate_t ps;
2805 int tmp, point, width, max;
2806
2807 if (end <= start)
2808 return 0;
2809 if (MB_CUR_MAX == 1 || rl_byte_oriented)
2810 /* this can happen in some cases where it's inconvenient to check */
2811 return (end - start);
2812
2813 memset (&ps, 0, sizeof (mbstate_t));
2814
2815 point = 0;
2816 max = end;
2817
2818 /* Try to short-circuit common cases. The adjustment to remove wrap_offset
2819 is done by the caller. */
2820 /* 1. prompt string */
2821 if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
2822 return (prompt_physical_chars + wrap_offset);
2823 /* 2. prompt string + line contents */
2824 else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
2825 {
2826 tmp = prompt_physical_chars + wrap_offset;
2827 /* XXX - try to call ourselves recursively with non-prompt portion */
2828 tmp += _rl_col_width (str, local_prompt_len, end, flags);
2829 return (tmp);
2830 }
2831
2832 while (point < start)
2833 {
2834 tmp = mbrlen (str + point, max, &ps);
2835 if (MB_INVALIDCH ((size_t)tmp))
2836 {
2837 /* In this case, the bytes are invalid or too short to compose a
2838 multibyte character, so we assume that the first byte represents
2839 a single character. */
2840 point++;
2841 max--;
2842
2843 /* Clear the state of the byte sequence, because in this case the
2844 effect of mbstate is undefined. */
2845 memset (&ps, 0, sizeof (mbstate_t));
2846 }
2847 else if (MB_NULLWCH (tmp))
2848 break; /* Found '\0' */
2849 else
2850 {
2851 point += tmp;
2852 max -= tmp;
2853 }
2854 }
2855
2856 /* If START is not a byte that starts a character, then POINT will be
2857 greater than START. In this case, assume that (POINT - START) gives
2858 a byte count that is the number of columns of difference. */
2859 width = point - start;
2860
2861 while (point < end)
2862 {
2863 tmp = mbrtowc (&wc, str + point, max, &ps);
2864 if (MB_INVALIDCH ((size_t)tmp))
2865 {
2866 /* In this case, the bytes are invalid or too short to compose a
2867 multibyte character, so we assume that the first byte represents
2868 a single character. */
2869 point++;
2870 max--;
2871
2872 /* and assume that the byte occupies a single column. */
2873 width++;
2874
2875 /* Clear the state of the byte sequence, because in this case the
2876 effect of mbstate is undefined. */
2877 memset (&ps, 0, sizeof (mbstate_t));
2878 }
2879 else if (MB_NULLWCH (tmp))
2880 break; /* Found '\0' */
2881 else
2882 {
2883 point += tmp;
2884 max -= tmp;
2885 tmp = WCWIDTH(wc);
2886 width += (tmp >= 0) ? tmp : 1;
2887 }
2888 }
2889
2890 width += point - end;
2891
2892 return width;
2893}
2894#endif /* HANDLE_MULTIBYTE */