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