blob: 4df1f734bec73d6405d60a9b49690ab0da4bb3f5 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* display.c -- readline redisplay facility. */
2
Chet Rameyac50fba2014-02-26 09:36:43 -05003/* Copyright (C) 1987-2013 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
Jari Aalto31859422009-01-12 13:36:28 +00005 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
Jari Aalto726f6381996-08-26 18:22:31 +00007
Jari Aalto31859422009-01-12 13:36:28 +00008 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
Jari Aalto726f6381996-08-26 18:22:31 +000011 (at your option) any later version.
12
Jari Aalto31859422009-01-12 13:36:28 +000013 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
Jari Aalto726f6381996-08-26 18:22:31 +000016 GNU General Public License for more details.
17
Jari Aalto31859422009-01-12 13:36:28 +000018 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
Jari Aalto726f6381996-08-26 18:22:31 +000022#define READLINE_LIBRARY
23
24#if defined (HAVE_CONFIG_H)
Jari Aaltoccc6cda1996-12-23 17:02:34 +000025# include <config.h>
Jari Aalto726f6381996-08-26 18:22:31 +000026#endif
27
Jari Aalto726f6381996-08-26 18:22:31 +000028#include <sys/types.h>
29
30#if defined (HAVE_UNISTD_H)
31# include <unistd.h>
32#endif /* HAVE_UNISTD_H */
33
Jari Aaltod166f041997-06-05 14:59:13 +000034#include "posixstat.h"
35
Jari Aalto726f6381996-08-26 18:22:31 +000036#if defined (HAVE_STDLIB_H)
37# include <stdlib.h>
38#else
39# include "ansi_stdlib.h"
40#endif /* HAVE_STDLIB_H */
41
Jari Aaltod166f041997-06-05 14:59:13 +000042#include <stdio.h>
43
Chet Rameyac50fba2014-02-26 09:36:43 -050044#ifdef __MSDOS__
45# include <pc.h>
46#endif
47
Jari Aalto726f6381996-08-26 18:22:31 +000048/* System-specific feature definitions and include files. */
49#include "rldefs.h"
Jari Aalto7117c2d2002-07-17 14:10:11 +000050#include "rlmbutil.h"
Jari Aalto726f6381996-08-26 18:22:31 +000051
Jari Aaltoccc6cda1996-12-23 17:02:34 +000052/* Termcap library stuff. */
53#include "tcap.h"
54
Jari Aalto726f6381996-08-26 18:22:31 +000055/* Some standard library routines. */
56#include "readline.h"
57#include "history.h"
58
Jari Aaltobb706242000-03-17 21:46:59 +000059#include "rlprivate.h"
60#include "xmalloc.h"
61
Jari Aalto726f6381996-08-26 18:22:31 +000062#if !defined (strchr) && !defined (__STDC__)
63extern char *strchr (), *strrchr ();
64#endif /* !strchr && !__STDC__ */
65
Jari Aaltof73dda02001-11-13 17:56:06 +000066static void update_line PARAMS((char *, char *, int, int, int, int));
67static void space_to_eol PARAMS((int));
68static void delete_chars PARAMS((int));
Jari Aalto7117c2d2002-07-17 14:10:11 +000069static void insert_some_chars PARAMS((char *, int, int));
Chet Rameyac50fba2014-02-26 09:36:43 -050070static void open_some_spaces PARAMS((int));
Jari Aaltof73dda02001-11-13 17:56:06 +000071static void cr PARAMS((void));
Jari Aaltoccc6cda1996-12-23 17:02:34 +000072
Jari Aalto31859422009-01-12 13:36:28 +000073/* State of visible and invisible lines. */
74struct line_state
75 {
76 char *line;
77 int *lbreaks;
78 int lbsize;
79#if defined (HANDLE_MULTIBYTE)
80 int *wrapped_line;
81 int wbsize;
82#endif
83 };
84
85/* The line display buffers. One is the line currently displayed on
86 the screen. The other is the line about to be displayed. */
87static struct line_state line_state_array[2];
88static struct line_state *line_state_visible = &line_state_array[0];
89static struct line_state *line_state_invisible = &line_state_array[1];
90static int line_structures_initialized = 0;
91
92/* Backwards-compatible names. */
93#define inv_lbreaks (line_state_invisible->lbreaks)
94#define inv_lbsize (line_state_invisible->lbsize)
95#define vis_lbreaks (line_state_visible->lbreaks)
96#define vis_lbsize (line_state_visible->lbsize)
97
98#define visible_line (line_state_visible->line)
99#define invisible_line (line_state_invisible->line)
100
Jari Aalto7117c2d2002-07-17 14:10:11 +0000101#if defined (HANDLE_MULTIBYTE)
Chet Ramey00018032011-11-21 20:51:19 -0500102static int _rl_col_width PARAMS((const char *, int, int, int));
Jari Aalto7117c2d2002-07-17 14:10:11 +0000103#else
Chet Ramey00018032011-11-21 20:51:19 -0500104# define _rl_col_width(l, s, e, f) (((e) <= (s)) ? 0 : (e) - (s))
Jari Aalto7117c2d2002-07-17 14:10:11 +0000105#endif
106
Jari Aalto726f6381996-08-26 18:22:31 +0000107/* Heuristic used to decide whether it is faster to move from CUR to NEW
Jari Aalto06285672006-10-10 14:15:34 +0000108 by backing up or outputting a carriage return and moving forward. CUR
109 and NEW are either both buffer positions or absolute screen positions. */
Jari Aalto726f6381996-08-26 18:22:31 +0000110#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
111
Jari Aalto06285672006-10-10 14:15:34 +0000112/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
113 buffer index in others. This macro is used when deciding whether the
114 current cursor position is in the middle of a prompt string containing
Jari Aalto31859422009-01-12 13:36:28 +0000115 invisible characters. XXX - might need to take `modmark' into account. */
Jari Aalto06285672006-10-10 14:15:34 +0000116#define PROMPT_ENDING_INDEX \
117 ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
118
119
Jari Aalto726f6381996-08-26 18:22:31 +0000120/* **************************************************************** */
121/* */
122/* Display stuff */
123/* */
124/* **************************************************************** */
125
126/* This is the stuff that is hard for me. I never seem to write good
127 display routines in C. Let's see how I do this time. */
128
129/* (PWP) Well... Good for a simple line updater, but totally ignores
130 the problems of input lines longer than the screen width.
131
132 update_line and the code that calls it makes a multiple line,
133 automatically wrapping line update. Careful attention needs
134 to be paid to the vertical position variables. */
135
136/* Keep two buffers; one which reflects the current contents of the
137 screen, and the other to draw what we think the new contents should
138 be. Then compare the buffers, and make whatever changes to the
139 screen itself that we should. Finally, make the buffer that we
140 just drew into be the one which reflects the current contents of the
141 screen, and place the cursor where it belongs.
142
143 Commands that want to can fix the display themselves, and then let
144 this function know that the display has been fixed by setting the
145 RL_DISPLAY_FIXED variable. This is good for efficiency. */
146
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000147/* Application-specific redisplay function. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000148rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000149
Jari Aalto726f6381996-08-26 18:22:31 +0000150/* Global variables declared here. */
151/* What YOU turn on when you have handled all redisplay yourself. */
152int rl_display_fixed = 0;
153
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000154int _rl_suppress_redisplay = 0;
Jari Aalto95732b42005-12-07 14:08:12 +0000155int _rl_want_redisplay = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000156
Jari Aalto726f6381996-08-26 18:22:31 +0000157/* The stuff that gets printed out before the actual text of the line.
158 This is usually pointing to rl_prompt. */
159char *rl_display_prompt = (char *)NULL;
160
161/* Pseudo-global variables declared here. */
Jari Aalto95732b42005-12-07 14:08:12 +0000162
Jari Aalto726f6381996-08-26 18:22:31 +0000163/* The visible cursor position. If you print some text, adjust this. */
Jari Aalto95732b42005-12-07 14:08:12 +0000164/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
165 supporting multibyte characters, and an absolute cursor position when
166 in such a locale. This is an artifact of the donated multibyte support.
167 Care must be taken when modifying its value. */
Jari Aalto726f6381996-08-26 18:22:31 +0000168int _rl_last_c_pos = 0;
169int _rl_last_v_pos = 0;
170
Jari Aalto95732b42005-12-07 14:08:12 +0000171static int cpos_adjusted;
Jari Aalto06285672006-10-10 14:15:34 +0000172static int cpos_buffer_position;
Chet Rameyac50fba2014-02-26 09:36:43 -0500173static int displaying_prompt_first_line;
Jari Aalto31859422009-01-12 13:36:28 +0000174static int prompt_multibyte_chars;
Jari Aalto95732b42005-12-07 14:08:12 +0000175
Jari Aalto726f6381996-08-26 18:22:31 +0000176/* Number of lines currently on screen minus 1. */
177int _rl_vis_botlin = 0;
178
179/* Variables used only in this file. */
180/* The last left edge of text that was displayed. This is used when
181 doing horizontal scrolling. It shifts in thirds of a screenwidth. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000182static int last_lmargin;
Jari Aalto726f6381996-08-26 18:22:31 +0000183
Jari Aalto726f6381996-08-26 18:22:31 +0000184/* A buffer for `modeline' messages. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500185static char *msg_buf = 0;
186static int msg_bufsiz = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000187
188/* Non-zero forces the redisplay even if we thought it was unnecessary. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000189static int forced_display;
Jari Aalto726f6381996-08-26 18:22:31 +0000190
191/* Default and initial buffer size. Can grow. */
192static int line_size = 1024;
193
Jari Aalto28ef6c32001-04-06 19:14:31 +0000194/* Variables to keep track of the expanded prompt string, which may
195 include invisible characters. */
196
Jari Aalto726f6381996-08-26 18:22:31 +0000197static char *local_prompt, *local_prompt_prefix;
Jari Aalto06285672006-10-10 14:15:34 +0000198static int local_prompt_len;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000199static int prompt_visible_length, prompt_prefix_length;
Jari Aalto726f6381996-08-26 18:22:31 +0000200
201/* The number of invisible characters in the line currently being
202 displayed on the screen. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000203static int visible_wrap_offset;
204
Jari Aalto28ef6c32001-04-06 19:14:31 +0000205/* The number of invisible characters in the prompt string. Static so it
206 can be shared between rl_redisplay and update_line */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000207static int wrap_offset;
208
Jari Aalto28ef6c32001-04-06 19:14:31 +0000209/* The index of the last invisible character in the prompt string. */
210static int prompt_last_invisible;
Jari Aalto726f6381996-08-26 18:22:31 +0000211
212/* The length (buffer offset) of the first line of the last (possibly
213 multi-line) buffer displayed on the screen. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000214static int visible_first_line_len;
Jari Aalto726f6381996-08-26 18:22:31 +0000215
Jari Aalto28ef6c32001-04-06 19:14:31 +0000216/* Number of invisible characters on the first physical line of the prompt.
217 Only valid when the number of physical characters in the prompt exceeds
218 (or is equal to) _rl_screenwidth. */
219static int prompt_invis_chars_first_line;
220
221static int prompt_last_screen_line;
222
Jari Aaltob80f6442004-07-27 13:29:18 +0000223static int prompt_physical_chars;
224
Jari Aalto31859422009-01-12 13:36:28 +0000225/* set to a non-zero value by rl_redisplay if we are marking modified history
226 lines and the current line is so marked. */
227static int modmark;
228
Jari Aalto95732b42005-12-07 14:08:12 +0000229/* Variables to save and restore prompt and display information. */
230
231/* These are getting numerous enough that it's time to create a struct. */
232
233static char *saved_local_prompt;
234static char *saved_local_prefix;
235static int saved_last_invisible;
236static int saved_visible_length;
237static int saved_prefix_length;
Jari Aalto06285672006-10-10 14:15:34 +0000238static int saved_local_length;
Jari Aalto95732b42005-12-07 14:08:12 +0000239static int saved_invis_chars_first_line;
240static int saved_physical_chars;
241
Chet Rameyac50fba2014-02-26 09:36:43 -0500242/* Return a character indicating the editing mode, for use in the prompt. */
243static int
244prompt_modechar ()
245{
246 if (rl_editing_mode == emacs_mode)
247 return '@';
248 else if (_rl_keymap == vi_insertion_keymap)
249 return '+'; /* vi insert mode */
250 else
251 return ':'; /* vi command mode */
252}
253
Jari Aalto726f6381996-08-26 18:22:31 +0000254/* Expand the prompt string S and return the number of visible
255 characters in *LP, if LP is not null. This is currently more-or-less
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000256 a placeholder for expansion. LIP, if non-null is a place to store the
Jari Aalto28ef6c32001-04-06 19:14:31 +0000257 index of the last invisible character in the returned string. NIFLP,
258 if non-zero, is a place to store the number of invisible characters in
Jari Aaltob80f6442004-07-27 13:29:18 +0000259 the first prompt line. The previous are used as byte counts -- indexes
260 into a character buffer. */
Jari Aalto726f6381996-08-26 18:22:31 +0000261
262/* Current implementation:
263 \001 (^A) start non-visible characters
264 \002 (^B) end non-visible characters
265 all characters except \001 and \002 (following a \001) are copied to
266 the returned string; all characters except those between \001 and
267 \002 are assumed to be `visible'. */
268
269static char *
Jari Aaltob80f6442004-07-27 13:29:18 +0000270expand_prompt (pmt, lp, lip, niflp, vlp)
Jari Aalto726f6381996-08-26 18:22:31 +0000271 char *pmt;
Jari Aaltob80f6442004-07-27 13:29:18 +0000272 int *lp, *lip, *niflp, *vlp;
Jari Aalto726f6381996-08-26 18:22:31 +0000273{
Jari Aalto06285672006-10-10 14:15:34 +0000274 char *r, *ret, *p, *igstart;
Jari Aaltoeb873672004-11-09 21:37:25 +0000275 int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
Jari Aalto726f6381996-08-26 18:22:31 +0000276
277 /* Short-circuit if we can. */
Jari Aaltob80f6442004-07-27 13:29:18 +0000278 if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000279 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500280 if (pmt == rl_prompt && _rl_show_mode_in_prompt)
281 {
282 l = strlen (pmt);
283 r = (char *)xmalloc (l + 2);
284 r[0] = prompt_modechar ();
285 strcpy (r + 1, pmt);
286 }
287 else
288 r = savestring (pmt);
289
Jari Aalto726f6381996-08-26 18:22:31 +0000290 if (lp)
291 *lp = strlen (r);
Jari Aaltob80f6442004-07-27 13:29:18 +0000292 if (lip)
293 *lip = 0;
294 if (niflp)
295 *niflp = 0;
296 if (vlp)
297 *vlp = lp ? *lp : strlen (r);
Jari Aalto726f6381996-08-26 18:22:31 +0000298 return r;
299 }
300
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000301 l = strlen (pmt);
Chet Rameyac50fba2014-02-26 09:36:43 -0500302 r = ret = (char *)xmalloc (l + 2);
303
304 rl = physchars = 0; /* move up here so mode show can set them */
305 if (pmt == rl_prompt && _rl_show_mode_in_prompt)
306 {
307 *r++ = prompt_modechar ();
308 rl = physchars = 1;
309 }
Jari Aalto28ef6c32001-04-06 19:14:31 +0000310
311 invfl = 0; /* invisible chars in first line of prompt */
Jari Aaltoeb873672004-11-09 21:37:25 +0000312 invflset = 0; /* we only want to set invfl once */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000313
Jari Aalto06285672006-10-10 14:15:34 +0000314 igstart = 0;
Chet Rameyac50fba2014-02-26 09:36:43 -0500315 for (ignoring = last = ninvis = 0, p = pmt; p && *p; p++)
Jari Aalto726f6381996-08-26 18:22:31 +0000316 {
317 /* This code strips the invisible character string markers
318 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
Jari Aalto06285672006-10-10 14:15:34 +0000319 if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
Jari Aalto726f6381996-08-26 18:22:31 +0000320 {
Jari Aalto06285672006-10-10 14:15:34 +0000321 ignoring = 1;
322 igstart = p;
Jari Aalto726f6381996-08-26 18:22:31 +0000323 continue;
324 }
325 else if (ignoring && *p == RL_PROMPT_END_IGNORE)
326 {
327 ignoring = 0;
Jari Aalto06285672006-10-10 14:15:34 +0000328 if (p != (igstart + 1))
Jari Aalto95732b42005-12-07 14:08:12 +0000329 last = r - ret - 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000330 continue;
331 }
332 else
333 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000334#if defined (HANDLE_MULTIBYTE)
335 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
336 {
337 pind = p - pmt;
338 ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
339 l = ind - pind;
340 while (l--)
341 *r++ = *p++;
342 if (!ignoring)
Jari Aaltoeb873672004-11-09 21:37:25 +0000343 {
Jari Aalto31859422009-01-12 13:36:28 +0000344 /* rl ends up being assigned to prompt_visible_length,
345 which is the number of characters in the buffer that
346 contribute to characters on the screen, which might
347 not be the same as the number of physical characters
348 on the screen in the presence of multibyte characters */
Jari Aaltoeb873672004-11-09 21:37:25 +0000349 rl += ind - pind;
Chet Ramey00018032011-11-21 20:51:19 -0500350 physchars += _rl_col_width (pmt, pind, ind, 0);
Jari Aaltoeb873672004-11-09 21:37:25 +0000351 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000352 else
353 ninvis += ind - pind;
354 p--; /* compensate for later increment */
355 }
Jari Aalto28ef6c32001-04-06 19:14:31 +0000356 else
Jari Aaltob80f6442004-07-27 13:29:18 +0000357#endif
358 {
359 *r++ = *p;
360 if (!ignoring)
Jari Aaltoeb873672004-11-09 21:37:25 +0000361 {
362 rl++; /* visible length byte counter */
363 physchars++;
364 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000365 else
366 ninvis++; /* invisible chars byte counter */
367 }
368
Jari Aaltoeb873672004-11-09 21:37:25 +0000369 if (invflset == 0 && rl >= _rl_screenwidth)
370 {
371 invfl = ninvis;
372 invflset = 1;
373 }
Jari Aalto726f6381996-08-26 18:22:31 +0000374 }
375 }
376
Jari Aalto28ef6c32001-04-06 19:14:31 +0000377 if (rl < _rl_screenwidth)
378 invfl = ninvis;
379
Jari Aalto726f6381996-08-26 18:22:31 +0000380 *r = '\0';
381 if (lp)
382 *lp = rl;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000383 if (lip)
384 *lip = last;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000385 if (niflp)
386 *niflp = invfl;
Jari Aaltob80f6442004-07-27 13:29:18 +0000387 if (vlp)
388 *vlp = physchars;
Jari Aalto726f6381996-08-26 18:22:31 +0000389 return ret;
390}
391
Jari Aaltobb706242000-03-17 21:46:59 +0000392/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
393 PMT and return the rest of PMT. */
394char *
395_rl_strip_prompt (pmt)
396 char *pmt;
397{
398 char *ret;
399
Jari Aaltob80f6442004-07-27 13:29:18 +0000400 ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
Jari Aaltobb706242000-03-17 21:46:59 +0000401 return ret;
402}
403
Chet Rameyac50fba2014-02-26 09:36:43 -0500404void
405_rl_reset_prompt ()
406{
407 rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
408}
409
Jari Aalto726f6381996-08-26 18:22:31 +0000410/*
411 * Expand the prompt string into the various display components, if
412 * necessary.
413 *
414 * local_prompt = expanded last line of string in rl_display_prompt
415 * (portion after the final newline)
416 * local_prompt_prefix = portion before last newline of rl_display_prompt,
417 * expanded via expand_prompt
Jari Aalto28ef6c32001-04-06 19:14:31 +0000418 * prompt_visible_length = number of visible characters in local_prompt
419 * prompt_prefix_length = number of visible characters in local_prompt_prefix
Jari Aalto726f6381996-08-26 18:22:31 +0000420 *
421 * This function is called once per call to readline(). It may also be
422 * called arbitrarily to expand the primary prompt.
423 *
424 * The return value is the number of visible characters on the last line
425 * of the (possibly multi-line) prompt.
426 */
427int
428rl_expand_prompt (prompt)
429 char *prompt;
430{
431 char *p, *t;
432 int c;
433
434 /* Clear out any saved values. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000435 FREE (local_prompt);
436 FREE (local_prompt_prefix);
437
Jari Aalto726f6381996-08-26 18:22:31 +0000438 local_prompt = local_prompt_prefix = (char *)0;
Jari Aalto06285672006-10-10 14:15:34 +0000439 local_prompt_len = 0;
Jari Aalto95732b42005-12-07 14:08:12 +0000440 prompt_last_invisible = prompt_invis_chars_first_line = 0;
441 prompt_visible_length = prompt_physical_chars = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000442
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000443 if (prompt == 0 || *prompt == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000444 return (0);
445
446 p = strrchr (prompt, '\n');
447 if (!p)
448 {
Jari Aalto28ef6c32001-04-06 19:14:31 +0000449 /* The prompt is only one logical line, though it might wrap. */
450 local_prompt = expand_prompt (prompt, &prompt_visible_length,
451 &prompt_last_invisible,
Jari Aaltob80f6442004-07-27 13:29:18 +0000452 &prompt_invis_chars_first_line,
453 &prompt_physical_chars);
Jari Aalto726f6381996-08-26 18:22:31 +0000454 local_prompt_prefix = (char *)0;
Jari Aalto06285672006-10-10 14:15:34 +0000455 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000456 return (prompt_visible_length);
Jari Aalto726f6381996-08-26 18:22:31 +0000457 }
458 else
459 {
460 /* The prompt spans multiple lines. */
461 t = ++p;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000462 local_prompt = expand_prompt (p, &prompt_visible_length,
463 &prompt_last_invisible,
Jari Aaltof1be6662008-11-18 13:15:12 +0000464 &prompt_invis_chars_first_line,
Jari Aaltoeb873672004-11-09 21:37:25 +0000465 &prompt_physical_chars);
Jari Aalto726f6381996-08-26 18:22:31 +0000466 c = *t; *t = '\0';
467 /* The portion of the prompt string up to and including the
468 final newline is now null-terminated. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000469 local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
470 (int *)NULL,
Jari Aaltof1be6662008-11-18 13:15:12 +0000471 (int *)NULL,
Jari Aaltoeb873672004-11-09 21:37:25 +0000472 (int *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +0000473 *t = c;
Jari Aalto06285672006-10-10 14:15:34 +0000474 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000475 return (prompt_prefix_length);
Jari Aalto726f6381996-08-26 18:22:31 +0000476 }
477}
478
Jari Aaltobb706242000-03-17 21:46:59 +0000479/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
480 arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
481 and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
482 increased. If the lines have already been allocated, this ensures that
483 they can hold at least MINSIZE characters. */
484static void
485init_line_structures (minsize)
486 int minsize;
487{
488 register int n;
489
490 if (invisible_line == 0) /* initialize it */
491 {
492 if (line_size < minsize)
493 line_size = minsize;
Jari Aaltof73dda02001-11-13 17:56:06 +0000494 visible_line = (char *)xmalloc (line_size);
495 invisible_line = (char *)xmalloc (line_size);
Jari Aaltobb706242000-03-17 21:46:59 +0000496 }
497 else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
498 {
499 line_size *= 2;
500 if (line_size < minsize)
501 line_size = minsize;
Jari Aaltof73dda02001-11-13 17:56:06 +0000502 visible_line = (char *)xrealloc (visible_line, line_size);
503 invisible_line = (char *)xrealloc (invisible_line, line_size);
Jari Aaltobb706242000-03-17 21:46:59 +0000504 }
505
506 for (n = minsize; n < line_size; n++)
507 {
508 visible_line[n] = 0;
509 invisible_line[n] = 1;
510 }
511
512 if (vis_lbreaks == 0)
513 {
514 /* should be enough. */
515 inv_lbsize = vis_lbsize = 256;
Jari Aalto31859422009-01-12 13:36:28 +0000516
517#if defined (HANDLE_MULTIBYTE)
518 line_state_visible->wbsize = vis_lbsize;
519 line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
520
521 line_state_invisible->wbsize = inv_lbsize;
522 line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
523#endif
524
Jari Aaltobb706242000-03-17 21:46:59 +0000525 inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
526 vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
527 inv_lbreaks[0] = vis_lbreaks[0] = 0;
528 }
Jari Aalto31859422009-01-12 13:36:28 +0000529
530 line_structures_initialized = 1;
Jari Aaltobb706242000-03-17 21:46:59 +0000531}
532
Jari Aalto726f6381996-08-26 18:22:31 +0000533/* Basic redisplay algorithm. */
534void
535rl_redisplay ()
536{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000537 register int in, out, c, linenum, cursor_linenum;
538 register char *line;
Jari Aalto06285672006-10-10 14:15:34 +0000539 int inv_botlin, lb_botlin, lb_linenum, o_cpos;
Jari Aalto31859422009-01-12 13:36:28 +0000540 int newlines, lpos, temp, n0, num, prompt_lines_estimate;
Jari Aalto726f6381996-08-26 18:22:31 +0000541 char *prompt_this_line;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000542#if defined (HANDLE_MULTIBYTE)
543 wchar_t wc;
544 size_t wc_bytes;
545 int wc_width;
546 mbstate_t ps;
547 int _rl_wrapped_multicolumn = 0;
548#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000549
Jari Aalto31859422009-01-12 13:36:28 +0000550 if (_rl_echoing_p == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000551 return;
552
Jari Aalto31859422009-01-12 13:36:28 +0000553 /* Block keyboard interrupts because this function manipulates global
554 data structures. */
555 _rl_block_sigint ();
Chet Ramey89a92862011-11-21 20:49:12 -0500556 RL_SETSTATE (RL_STATE_REDISPLAYING);
Jari Aalto31859422009-01-12 13:36:28 +0000557
Jari Aalto726f6381996-08-26 18:22:31 +0000558 if (!rl_display_prompt)
559 rl_display_prompt = "";
560
Jari Aalto31859422009-01-12 13:36:28 +0000561 if (line_structures_initialized == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000562 {
Jari Aaltobb706242000-03-17 21:46:59 +0000563 init_line_structures (0);
Jari Aalto726f6381996-08-26 18:22:31 +0000564 rl_on_new_line ();
565 }
566
567 /* Draw the line into the buffer. */
Jari Aalto06285672006-10-10 14:15:34 +0000568 cpos_buffer_position = -1;
Jari Aalto726f6381996-08-26 18:22:31 +0000569
Jari Aalto31859422009-01-12 13:36:28 +0000570 prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
571
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000572 line = invisible_line;
573 out = inv_botlin = 0;
574
Jari Aalto726f6381996-08-26 18:22:31 +0000575 /* Mark the line as modified or not. We only do this for history
576 lines. */
Jari Aaltob80f6442004-07-27 13:29:18 +0000577 modmark = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000578 if (_rl_mark_modified_lines && current_history () && rl_undo_list)
579 {
580 line[out++] = '*';
581 line[out] = '\0';
Jari Aaltob80f6442004-07-27 13:29:18 +0000582 modmark = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000583 }
584
585 /* If someone thought that the redisplay was handled, but the currently
586 visible line has a different modification state than the one about
587 to become visible, then correct the caller's misconception. */
588 if (visible_line[0] != invisible_line[0])
589 rl_display_fixed = 0;
590
591 /* If the prompt to be displayed is the `primary' readline prompt (the
592 one passed to readline()), use the values we have already expanded.
593 If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
594 number of non-visible characters in the prompt string. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000595 if (rl_display_prompt == rl_prompt || local_prompt)
Jari Aalto726f6381996-08-26 18:22:31 +0000596 {
Jari Aalto726f6381996-08-26 18:22:31 +0000597 if (local_prompt_prefix && forced_display)
598 _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
599
Jari Aalto06285672006-10-10 14:15:34 +0000600 if (local_prompt_len > 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000601 {
Jari Aalto06285672006-10-10 14:15:34 +0000602 temp = local_prompt_len + out + 2;
Jari Aaltob72432f1999-02-19 17:11:39 +0000603 if (temp >= line_size)
604 {
605 line_size = (temp + 1024) - (temp % 1024);
Jari Aaltof73dda02001-11-13 17:56:06 +0000606 visible_line = (char *)xrealloc (visible_line, line_size);
607 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
Jari Aaltob72432f1999-02-19 17:11:39 +0000608 }
Jari Aalto06285672006-10-10 14:15:34 +0000609 strncpy (line + out, local_prompt, local_prompt_len);
610 out += local_prompt_len;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000611 }
Jari Aalto726f6381996-08-26 18:22:31 +0000612 line[out] = '\0';
Jari Aalto06285672006-10-10 14:15:34 +0000613 wrap_offset = local_prompt_len - prompt_visible_length;
Jari Aalto726f6381996-08-26 18:22:31 +0000614 }
615 else
616 {
617 int pmtlen;
618 prompt_this_line = strrchr (rl_display_prompt, '\n');
619 if (!prompt_this_line)
620 prompt_this_line = rl_display_prompt;
621 else
622 {
623 prompt_this_line++;
Jari Aaltobb706242000-03-17 21:46:59 +0000624 pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
Jari Aalto726f6381996-08-26 18:22:31 +0000625 if (forced_display)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000626 {
Jari Aaltobb706242000-03-17 21:46:59 +0000627 _rl_output_some_chars (rl_display_prompt, pmtlen);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000628 /* Make sure we are at column zero even after a newline,
629 regardless of the state of terminal output processing. */
Jari Aaltobb706242000-03-17 21:46:59 +0000630 if (pmtlen < 2 || prompt_this_line[-2] != '\r')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000631 cr ();
632 }
Jari Aalto726f6381996-08-26 18:22:31 +0000633 }
634
Jari Aaltob80f6442004-07-27 13:29:18 +0000635 prompt_physical_chars = pmtlen = strlen (prompt_this_line);
Jari Aaltob72432f1999-02-19 17:11:39 +0000636 temp = pmtlen + out + 2;
637 if (temp >= line_size)
638 {
639 line_size = (temp + 1024) - (temp % 1024);
Jari Aaltof73dda02001-11-13 17:56:06 +0000640 visible_line = (char *)xrealloc (visible_line, line_size);
641 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
Jari Aaltob72432f1999-02-19 17:11:39 +0000642 }
Jari Aalto726f6381996-08-26 18:22:31 +0000643 strncpy (line + out, prompt_this_line, pmtlen);
644 out += pmtlen;
645 line[out] = '\0';
Jari Aalto28ef6c32001-04-06 19:14:31 +0000646 wrap_offset = prompt_invis_chars_first_line = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000647 }
648
Jari Aaltobb706242000-03-17 21:46:59 +0000649#define CHECK_INV_LBREAKS() \
650 do { \
651 if (newlines >= (inv_lbsize - 2)) \
652 { \
653 inv_lbsize *= 2; \
654 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
655 } \
656 } while (0)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000657
658#if defined (HANDLE_MULTIBYTE)
659#define CHECK_LPOS() \
660 do { \
661 lpos++; \
662 if (lpos >= _rl_screenwidth) \
663 { \
664 if (newlines >= (inv_lbsize - 2)) \
665 { \
666 inv_lbsize *= 2; \
667 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
Jari Aalto7117c2d2002-07-17 14:10:11 +0000668 } \
669 inv_lbreaks[++newlines] = out; \
Jari Aalto31859422009-01-12 13:36:28 +0000670 if (newlines >= (line_state_invisible->wbsize - 1)) \
671 { \
672 line_state_invisible->wbsize *= 2; \
673 line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
674 } \
675 line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \
Jari Aalto7117c2d2002-07-17 14:10:11 +0000676 lpos = 0; \
677 } \
678 } while (0)
679#else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000680#define CHECK_LPOS() \
681 do { \
Jari Aaltob72432f1999-02-19 17:11:39 +0000682 lpos++; \
Jari Aalto28ef6c32001-04-06 19:14:31 +0000683 if (lpos >= _rl_screenwidth) \
Jari Aaltob72432f1999-02-19 17:11:39 +0000684 { \
Jari Aaltobb706242000-03-17 21:46:59 +0000685 if (newlines >= (inv_lbsize - 2)) \
686 { \
687 inv_lbsize *= 2; \
688 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
689 } \
Jari Aaltob72432f1999-02-19 17:11:39 +0000690 inv_lbreaks[++newlines] = out; \
691 lpos = 0; \
692 } \
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000693 } while (0)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000694#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000695
696 /* inv_lbreaks[i] is where line i starts in the buffer. */
697 inv_lbreaks[newlines = 0] = 0;
Jari Aaltob80f6442004-07-27 13:29:18 +0000698 lpos = prompt_physical_chars + modmark;
Jari Aaltob80f6442004-07-27 13:29:18 +0000699
Jari Aalto7117c2d2002-07-17 14:10:11 +0000700#if defined (HANDLE_MULTIBYTE)
Jari Aalto31859422009-01-12 13:36:28 +0000701 memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
Jari Aaltoeb873672004-11-09 21:37:25 +0000702 num = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000703#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000704
Jari Aalto28ef6c32001-04-06 19:14:31 +0000705 /* prompt_invis_chars_first_line is the number of invisible characters in
706 the first physical line of the prompt.
707 wrap_offset - prompt_invis_chars_first_line is the number of invis
Jari Aalto31859422009-01-12 13:36:28 +0000708 chars on the second (or, more generally, last) line. */
709
710 /* This is zero-based, used to set the newlines */
711 prompt_lines_estimate = lpos / _rl_screenwidth;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000712
713 /* what if lpos is already >= _rl_screenwidth before we start drawing the
Jari Aaltod166f041997-06-05 14:59:13 +0000714 contents of the command line? */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000715 while (lpos >= _rl_screenwidth)
Jari Aaltod166f041997-06-05 14:59:13 +0000716 {
Jari Aalto06285672006-10-10 14:15:34 +0000717 int z;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000718 /* fix from Darin Johnson <darin@acuson.com> for prompt string with
719 invisible characters that is longer than the screen width. The
720 prompt_invis_chars_first_line variable could be made into an array
721 saying how many invisible characters there are per line, but that's
722 probably too much work for the benefit gained. How many people have
Jari Aaltob80f6442004-07-27 13:29:18 +0000723 prompts that exceed two physical lines?
724 Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
Jari Aaltoeb873672004-11-09 21:37:25 +0000725#if defined (HANDLE_MULTIBYTE)
Jari Aalto31859422009-01-12 13:36:28 +0000726 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
Jari Aaltoeb873672004-11-09 21:37:25 +0000727 {
Jari Aalto06285672006-10-10 14:15:34 +0000728 n0 = num;
729 temp = local_prompt_len;
730 while (num < temp)
Jari Aaltoeb873672004-11-09 21:37:25 +0000731 {
Chet Ramey00018032011-11-21 20:51:19 -0500732 z = _rl_col_width (local_prompt, n0, num, 1);
Jari Aalto06285672006-10-10 14:15:34 +0000733 if (z > _rl_screenwidth)
734 {
735 num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
736 break;
737 }
738 else if (z == _rl_screenwidth)
739 break;
740 num++;
Jari Aaltoeb873672004-11-09 21:37:25 +0000741 }
Jari Aalto06285672006-10-10 14:15:34 +0000742 temp = num;
Jari Aaltoeb873672004-11-09 21:37:25 +0000743 }
Jari Aalto06285672006-10-10 14:15:34 +0000744 else
Jari Aaltoeb873672004-11-09 21:37:25 +0000745#endif /* !HANDLE_MULTIBYTE */
Jari Aalto06285672006-10-10 14:15:34 +0000746 temp = ((newlines + 1) * _rl_screenwidth);
747
748 /* Now account for invisible characters in the current line. */
Jari Aalto31859422009-01-12 13:36:28 +0000749 /* XXX - this assumes that the invisible characters may be split, but only
750 between the first and the last lines. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500751 temp += (newlines == 0) ? prompt_invis_chars_first_line
752 : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line);
753
Jari Aaltod166f041997-06-05 14:59:13 +0000754 inv_lbreaks[++newlines] = temp;
Jari Aaltoeb873672004-11-09 21:37:25 +0000755#if defined (HANDLE_MULTIBYTE)
Jari Aalto31859422009-01-12 13:36:28 +0000756 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
Chet Ramey00018032011-11-21 20:51:19 -0500757 lpos -= _rl_col_width (local_prompt, n0, num, 1);
Jari Aalto06285672006-10-10 14:15:34 +0000758 else
Jari Aaltoeb873672004-11-09 21:37:25 +0000759#endif
Jari Aalto06285672006-10-10 14:15:34 +0000760 lpos -= _rl_screenwidth;
Jari Aaltod166f041997-06-05 14:59:13 +0000761 }
762
Jari Aalto28ef6c32001-04-06 19:14:31 +0000763 prompt_last_screen_line = newlines;
764
765 /* Draw the rest of the line (after the prompt) into invisible_line, keeping
Jari Aalto06285672006-10-10 14:15:34 +0000766 track of where the cursor is (cpos_buffer_position), the number of the line containing
Jari Aalto28ef6c32001-04-06 19:14:31 +0000767 the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
768 It maintains an array of line breaks for display (inv_lbreaks).
769 This handles expanding tabs for display and displaying meta characters. */
Jari Aaltod166f041997-06-05 14:59:13 +0000770 lb_linenum = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000771#if defined (HANDLE_MULTIBYTE)
772 in = 0;
773 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
774 {
775 memset (&ps, 0, sizeof (mbstate_t));
Chet Ramey00018032011-11-21 20:51:19 -0500776 /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000777 wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
778 }
779 else
780 wc_bytes = 1;
781 while (in < rl_end)
782#else
Jari Aaltod166f041997-06-05 14:59:13 +0000783 for (in = 0; in < rl_end; in++)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000784#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000785 {
786 c = (unsigned char)rl_line_buffer[in];
787
Jari Aalto7117c2d2002-07-17 14:10:11 +0000788#if defined (HANDLE_MULTIBYTE)
789 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
790 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000791 if (MB_INVALIDCH (wc_bytes))
Jari Aalto7117c2d2002-07-17 14:10:11 +0000792 {
793 /* Byte sequence is invalid or shortened. Assume that the
794 first byte represents a character. */
795 wc_bytes = 1;
796 /* Assume that a character occupies a single column. */
797 wc_width = 1;
798 memset (&ps, 0, sizeof (mbstate_t));
799 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000800 else if (MB_NULLWCH (wc_bytes))
Jari Aalto7117c2d2002-07-17 14:10:11 +0000801 break; /* Found '\0' */
802 else
803 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500804 temp = WCWIDTH (wc);
Jari Aaltob80f6442004-07-27 13:29:18 +0000805 wc_width = (temp >= 0) ? temp : 1;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000806 }
807 }
808#endif
809
Jari Aalto726f6381996-08-26 18:22:31 +0000810 if (out + 8 >= line_size) /* XXX - 8 for \t */
811 {
812 line_size *= 2;
Jari Aaltof73dda02001-11-13 17:56:06 +0000813 visible_line = (char *)xrealloc (visible_line, line_size);
814 invisible_line = (char *)xrealloc (invisible_line, line_size);
Jari Aalto726f6381996-08-26 18:22:31 +0000815 line = invisible_line;
816 }
817
818 if (in == rl_point)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000819 {
Jari Aalto06285672006-10-10 14:15:34 +0000820 cpos_buffer_position = out;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000821 lb_linenum = newlines;
822 }
Jari Aalto726f6381996-08-26 18:22:31 +0000823
Jari Aalto7117c2d2002-07-17 14:10:11 +0000824#if defined (HANDLE_MULTIBYTE)
825 if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
826#else
Jari Aalto726f6381996-08-26 18:22:31 +0000827 if (META_CHAR (c))
Jari Aalto7117c2d2002-07-17 14:10:11 +0000828#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000829 {
830 if (_rl_output_meta_chars == 0)
831 {
832 sprintf (line + out, "\\%o", c);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000833
Jari Aalto28ef6c32001-04-06 19:14:31 +0000834 if (lpos + 4 >= _rl_screenwidth)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000835 {
Jari Aalto28ef6c32001-04-06 19:14:31 +0000836 temp = _rl_screenwidth - lpos;
Jari Aaltobb706242000-03-17 21:46:59 +0000837 CHECK_INV_LBREAKS ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000838 inv_lbreaks[++newlines] = out + temp;
839 lpos = 4 - temp;
840 }
841 else
842 lpos += 4;
843
Jari Aalto726f6381996-08-26 18:22:31 +0000844 out += 4;
845 }
846 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000847 {
848 line[out++] = c;
849 CHECK_LPOS();
850 }
Jari Aalto726f6381996-08-26 18:22:31 +0000851 }
852#if defined (DISPLAY_TABS)
853 else if (c == '\t')
854 {
Jari Aalto28ef6c32001-04-06 19:14:31 +0000855 register int newout;
Jari Aaltob72432f1999-02-19 17:11:39 +0000856
857#if 0
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000858 newout = (out | (int)7) + 1;
Jari Aaltob72432f1999-02-19 17:11:39 +0000859#else
860 newout = out + 8 - lpos % 8;
861#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000862 temp = newout - out;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000863 if (lpos + temp >= _rl_screenwidth)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000864 {
865 register int temp2;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000866 temp2 = _rl_screenwidth - lpos;
Jari Aaltobb706242000-03-17 21:46:59 +0000867 CHECK_INV_LBREAKS ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000868 inv_lbreaks[++newlines] = out + temp2;
869 lpos = temp - temp2;
870 while (out < newout)
871 line[out++] = ' ';
872 }
873 else
874 {
875 while (out < newout)
876 line[out++] = ' ';
877 lpos += temp;
878 }
Jari Aalto726f6381996-08-26 18:22:31 +0000879 }
880#endif
Jari Aalto28ef6c32001-04-06 19:14:31 +0000881 else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
Jari Aaltob72432f1999-02-19 17:11:39 +0000882 {
883 line[out++] = '\0'; /* XXX - sentinel */
Jari Aaltobb706242000-03-17 21:46:59 +0000884 CHECK_INV_LBREAKS ();
Jari Aaltob72432f1999-02-19 17:11:39 +0000885 inv_lbreaks[++newlines] = out;
886 lpos = 0;
887 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000888 else if (CTRL_CHAR (c) || c == RUBOUT)
Jari Aalto726f6381996-08-26 18:22:31 +0000889 {
890 line[out++] = '^';
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000891 CHECK_LPOS();
892 line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
893 CHECK_LPOS();
Jari Aalto726f6381996-08-26 18:22:31 +0000894 }
895 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000896 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000897#if defined (HANDLE_MULTIBYTE)
898 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
899 {
900 register int i;
901
902 _rl_wrapped_multicolumn = 0;
903
904 if (_rl_screenwidth < lpos + wc_width)
905 for (i = lpos; i < _rl_screenwidth; i++)
906 {
907 /* The space will be removed in update_line() */
908 line[out++] = ' ';
909 _rl_wrapped_multicolumn++;
910 CHECK_LPOS();
911 }
912 if (in == rl_point)
913 {
Jari Aalto06285672006-10-10 14:15:34 +0000914 cpos_buffer_position = out;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000915 lb_linenum = newlines;
916 }
917 for (i = in; i < in+wc_bytes; i++)
918 line[out++] = rl_line_buffer[i];
919 for (i = 0; i < wc_width; i++)
920 CHECK_LPOS();
921 }
922 else
923 {
924 line[out++] = c;
925 CHECK_LPOS();
926 }
927#else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000928 line[out++] = c;
929 CHECK_LPOS();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000930#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000931 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000932
933#if defined (HANDLE_MULTIBYTE)
934 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
935 {
936 in += wc_bytes;
Chet Ramey00018032011-11-21 20:51:19 -0500937 /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000938 wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
939 }
940 else
941 in++;
942#endif
943
Jari Aalto726f6381996-08-26 18:22:31 +0000944 }
945 line[out] = '\0';
Jari Aalto06285672006-10-10 14:15:34 +0000946 if (cpos_buffer_position < 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000947 {
Jari Aalto06285672006-10-10 14:15:34 +0000948 cpos_buffer_position = out;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000949 lb_linenum = newlines;
950 }
951
952 inv_botlin = lb_botlin = newlines;
Jari Aaltobb706242000-03-17 21:46:59 +0000953 CHECK_INV_LBREAKS ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000954 inv_lbreaks[newlines+1] = out;
955 cursor_linenum = lb_linenum;
Jari Aalto726f6381996-08-26 18:22:31 +0000956
Jari Aalto06285672006-10-10 14:15:34 +0000957 /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
Jari Aalto28ef6c32001-04-06 19:14:31 +0000958 CURSOR_LINENUM == line number where the cursor should be placed. */
Jari Aalto726f6381996-08-26 18:22:31 +0000959
960 /* PWP: now is when things get a bit hairy. The visible and invisible
961 line buffers are really multiple lines, which would wrap every
962 (screenwidth - 1) characters. Go through each in turn, finding
963 the changed region and updating it. The line order is top to bottom. */
964
965 /* If we can move the cursor up and down, then use multiple lines,
966 otherwise, let long lines display in a single terminal line, and
967 horizontally scroll it. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500968 displaying_prompt_first_line = 1;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000969 if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
Jari Aalto726f6381996-08-26 18:22:31 +0000970 {
Jari Aalto95732b42005-12-07 14:08:12 +0000971 int nleft, pos, changed_screen_line, tx;
Jari Aalto726f6381996-08-26 18:22:31 +0000972
973 if (!rl_display_fixed || forced_display)
974 {
975 forced_display = 0;
976
977 /* If we have more than a screenful of material to display, then
978 only display a screenful. We should display the last screen,
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000979 not the first. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000980 if (out >= _rl_screenchars)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000981 {
982 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
983 out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
984 else
985 out = _rl_screenchars - 1;
986 }
Jari Aalto726f6381996-08-26 18:22:31 +0000987
988 /* The first line is at character position 0 in the buffer. The
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000989 second and subsequent lines start at inv_lbreaks[N], offset by
990 OFFSET (which has already been calculated above). */
Jari Aalto726f6381996-08-26 18:22:31 +0000991
Jari Aaltof1be6662008-11-18 13:15:12 +0000992#define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
993#define WRAP_OFFSET(line, offset) ((line == 0) \
994 ? (offset ? INVIS_FIRST() : 0) \
995 : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
Jari Aalto726f6381996-08-26 18:22:31 +0000996#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000997#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
998#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
999#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
Jari Aalto726f6381996-08-26 18:22:31 +00001000#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001001#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
Jari Aalto726f6381996-08-26 18:22:31 +00001002
Chet Ramey00018032011-11-21 20:51:19 -05001003#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
1004 _rl_last_c_pos != o_cpos && \
1005 _rl_last_c_pos > wrap_offset && \
1006 o_cpos < prompt_last_invisible)
1007
Jari Aalto726f6381996-08-26 18:22:31 +00001008 /* For each line in the buffer, do the updating display. */
1009 for (linenum = 0; linenum <= inv_botlin; linenum++)
1010 {
Jari Aalto06285672006-10-10 14:15:34 +00001011 /* This can lead us astray if we execute a program that changes
1012 the locale from a non-multibyte to a multibyte one. */
Jari Aalto95732b42005-12-07 14:08:12 +00001013 o_cpos = _rl_last_c_pos;
1014 cpos_adjusted = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001015 update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001016 VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
Jari Aalto726f6381996-08-26 18:22:31 +00001017
Jari Aalto95732b42005-12-07 14:08:12 +00001018 /* update_line potentially changes _rl_last_c_pos, but doesn't
1019 take invisible characters into account, since _rl_last_c_pos
1020 is an absolute cursor position in a multibyte locale. See
1021 if compensating here is the right thing, or if we have to
Jari Aalto31859422009-01-12 13:36:28 +00001022 change update_line itself. There are several cases in which
Jari Aalto95732b42005-12-07 14:08:12 +00001023 update_line adjusts _rl_last_c_pos itself (so it can pass
1024 _rl_move_cursor_relative accurate values); it communicates
Jari Aalto06285672006-10-10 14:15:34 +00001025 this back by setting cpos_adjusted. If we assume that
1026 _rl_last_c_pos is correct (an absolute cursor position) each
1027 time update_line is called, then we can assume in our
1028 calculations that o_cpos does not need to be adjusted by
1029 wrap_offset. */
Chet Ramey00018032011-11-21 20:51:19 -05001030 if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
Jari Aaltof1be6662008-11-18 13:15:12 +00001031 _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
1032 else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
1033 (MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1034 cpos_adjusted == 0 &&
1035 _rl_last_c_pos != o_cpos &&
1036 _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
1037 _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
Jari Aalto95732b42005-12-07 14:08:12 +00001038
Jari Aalto726f6381996-08-26 18:22:31 +00001039 /* If this is the line with the prompt, we might need to
1040 compensate for invisible characters in the new line. Do
1041 this only if there is not more than one new line (which
1042 implies that we completely overwrite the old visible line)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001043 and the new line is shorter than the old. Make sure we are
1044 at the end of the new line before clearing. */
Jari Aalto726f6381996-08-26 18:22:31 +00001045 if (linenum == 0 &&
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001046 inv_botlin == 0 && _rl_last_c_pos == out &&
Jari Aalto726f6381996-08-26 18:22:31 +00001047 (wrap_offset > visible_wrap_offset) &&
1048 (_rl_last_c_pos < visible_first_line_len))
1049 {
Jari Aalto95732b42005-12-07 14:08:12 +00001050 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1051 nleft = _rl_screenwidth - _rl_last_c_pos;
1052 else
1053 nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
Jari Aalto726f6381996-08-26 18:22:31 +00001054 if (nleft)
Jari Aaltod166f041997-06-05 14:59:13 +00001055 _rl_clear_to_eol (nleft);
Jari Aalto726f6381996-08-26 18:22:31 +00001056 }
Jari Aalto31859422009-01-12 13:36:28 +00001057#if 0
1058 /* This segment is intended to handle the case where the prompt
1059 has invisible characters on the second line and the new line
1060 to be displayed needs to clear the rest of the old characters
1061 out (e.g., when printing the i-search prompt). In general,
1062 the case of the new line being shorter than the old.
1063 Incomplete */
1064 else if (linenum == prompt_last_screen_line &&
1065 prompt_physical_chars > _rl_screenwidth &&
1066 wrap_offset != prompt_invis_chars_first_line &&
1067 _rl_last_c_pos == out &&
1068#endif
1069
Jari Aalto726f6381996-08-26 18:22:31 +00001070
1071 /* Since the new first line is now visible, save its length. */
1072 if (linenum == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001073 visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
Jari Aalto726f6381996-08-26 18:22:31 +00001074 }
1075
1076 /* We may have deleted some lines. If so, clear the left over
1077 blank ones at the bottom out. */
1078 if (_rl_vis_botlin > inv_botlin)
1079 {
1080 char *tt;
1081 for (; linenum <= _rl_vis_botlin; linenum++)
1082 {
1083 tt = VIS_CHARS (linenum);
1084 _rl_move_vert (linenum);
1085 _rl_move_cursor_relative (0, tt);
Jari Aaltod166f041997-06-05 14:59:13 +00001086 _rl_clear_to_eol
Jari Aalto28ef6c32001-04-06 19:14:31 +00001087 ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
Jari Aalto726f6381996-08-26 18:22:31 +00001088 }
1089 }
1090 _rl_vis_botlin = inv_botlin;
1091
Jari Aalto726f6381996-08-26 18:22:31 +00001092 /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
1093 different screen line during this redisplay. */
1094 changed_screen_line = _rl_last_v_pos != cursor_linenum;
1095 if (changed_screen_line)
1096 {
1097 _rl_move_vert (cursor_linenum);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001098 /* If we moved up to the line with the prompt using _rl_term_up,
Jari Aaltob72432f1999-02-19 17:11:39 +00001099 the physical cursor position on the screen stays the same,
1100 but the buffer position needs to be adjusted to account
1101 for invisible characters. */
Jari Aalto95732b42005-12-07 14:08:12 +00001102 if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
Jari Aaltob72432f1999-02-19 17:11:39 +00001103 _rl_last_c_pos += wrap_offset;
Jari Aalto726f6381996-08-26 18:22:31 +00001104 }
1105
1106 /* We have to reprint the prompt if it contains invisible
1107 characters, since it's not generally OK to just reprint
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001108 the characters from the current cursor position. But we
1109 only need to reprint it if the cursor is before the last
1110 invisible character in the prompt string. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001111 nleft = prompt_visible_length + wrap_offset;
Jari Aalto726f6381996-08-26 18:22:31 +00001112 if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
Jari Aalto06285672006-10-10 14:15:34 +00001113#if 0
1114 _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
1115#else
1116 _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
1117#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001118 {
Jari Aaltobb706242000-03-17 21:46:59 +00001119#if defined (__MSDOS__)
1120 putc ('\r', rl_outstream);
1121#else
Jari Aalto28ef6c32001-04-06 19:14:31 +00001122 if (_rl_term_cr)
1123 tputs (_rl_term_cr, 1, _rl_output_character_function);
Jari Aaltobb706242000-03-17 21:46:59 +00001124#endif
Jari Aalto31859422009-01-12 13:36:28 +00001125 if (modmark)
1126 _rl_output_some_chars ("*", 1);
1127
Jari Aalto726f6381996-08-26 18:22:31 +00001128 _rl_output_some_chars (local_prompt, nleft);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001129 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Chet Ramey00018032011-11-21 20:51:19 -05001130 _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001131 else
Jari Aalto31859422009-01-12 13:36:28 +00001132 _rl_last_c_pos = nleft + modmark;
Jari Aalto726f6381996-08-26 18:22:31 +00001133 }
1134
1135 /* Where on that line? And where does that line start
1136 in the buffer? */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001137 pos = inv_lbreaks[cursor_linenum];
Jari Aalto726f6381996-08-26 18:22:31 +00001138 /* nleft == number of characters in the line buffer between the
Jari Aalto06285672006-10-10 14:15:34 +00001139 start of the line and the desired cursor position. */
1140 nleft = cpos_buffer_position - pos;
Jari Aalto726f6381996-08-26 18:22:31 +00001141
Jari Aalto95732b42005-12-07 14:08:12 +00001142 /* NLEFT is now a number of characters in a buffer. When in a
1143 multibyte locale, however, _rl_last_c_pos is an absolute cursor
1144 position that doesn't take invisible characters in the prompt
1145 into account. We use a fudge factor to compensate. */
1146
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001147 /* Since _rl_backspace() doesn't know about invisible characters in the
Jari Aalto726f6381996-08-26 18:22:31 +00001148 prompt, and there's no good way to tell it, we compensate for
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001149 those characters here and call _rl_backspace() directly. */
Jari Aalto726f6381996-08-26 18:22:31 +00001150 if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
1151 {
Jari Aalto06285672006-10-10 14:15:34 +00001152 /* TX == new physical cursor position in multibyte locale. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001153 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Chet Ramey00018032011-11-21 20:51:19 -05001154 tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001155 else
Jari Aalto95732b42005-12-07 14:08:12 +00001156 tx = nleft;
Jari Aaltof1be6662008-11-18 13:15:12 +00001157 if (tx >= 0 && _rl_last_c_pos > tx)
Jari Aalto95732b42005-12-07 14:08:12 +00001158 {
1159 _rl_backspace (_rl_last_c_pos - tx); /* XXX */
1160 _rl_last_c_pos = tx;
1161 }
Jari Aalto726f6381996-08-26 18:22:31 +00001162 }
1163
Jari Aalto95732b42005-12-07 14:08:12 +00001164 /* We need to note that in a multibyte locale we are dealing with
1165 _rl_last_c_pos as an absolute cursor position, but moving to a
1166 point specified by a buffer position (NLEFT) that doesn't take
1167 invisible characters into account. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001168 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1169 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1170 else if (nleft != _rl_last_c_pos)
Jari Aalto726f6381996-08-26 18:22:31 +00001171 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1172 }
1173 }
1174 else /* Do horizontal scrolling. */
1175 {
1176#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
1177 int lmargin, ndisp, nleft, phys_c_pos, t;
1178
1179 /* Always at top line. */
1180 _rl_last_v_pos = 0;
1181
1182 /* Compute where in the buffer the displayed line should start. This
1183 will be LMARGIN. */
1184
1185 /* The number of characters that will be displayed before the cursor. */
Jari Aalto06285672006-10-10 14:15:34 +00001186 ndisp = cpos_buffer_position - wrap_offset;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001187 nleft = prompt_visible_length + wrap_offset;
Jari Aalto726f6381996-08-26 18:22:31 +00001188 /* Where the new cursor position will be on the screen. This can be
Jari Aaltob72432f1999-02-19 17:11:39 +00001189 longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
Jari Aalto06285672006-10-10 14:15:34 +00001190 phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001191 t = _rl_screenwidth / 3;
Jari Aalto726f6381996-08-26 18:22:31 +00001192
1193 /* If the number of characters had already exceeded the screenwidth,
Jari Aaltob72432f1999-02-19 17:11:39 +00001194 last_lmargin will be > 0. */
Jari Aalto726f6381996-08-26 18:22:31 +00001195
1196 /* If the number of characters to be displayed is more than the screen
Jari Aaltob72432f1999-02-19 17:11:39 +00001197 width, compute the starting offset so that the cursor is about
1198 two-thirds of the way across the screen. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001199 if (phys_c_pos > _rl_screenwidth - 2)
Jari Aalto726f6381996-08-26 18:22:31 +00001200 {
Jari Aalto06285672006-10-10 14:15:34 +00001201 lmargin = cpos_buffer_position - (2 * t);
Jari Aalto726f6381996-08-26 18:22:31 +00001202 if (lmargin < 0)
1203 lmargin = 0;
1204 /* If the left margin would be in the middle of a prompt with
1205 invisible characters, don't display the prompt at all. */
1206 if (wrap_offset && lmargin > 0 && lmargin < nleft)
1207 lmargin = nleft;
1208 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00001209 else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
Jari Aaltob72432f1999-02-19 17:11:39 +00001210 lmargin = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001211 else if (phys_c_pos < 1)
1212 {
1213 /* If we are moving back towards the beginning of the line and
1214 the last margin is no longer correct, compute a new one. */
Jari Aalto06285672006-10-10 14:15:34 +00001215 lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */
Jari Aalto726f6381996-08-26 18:22:31 +00001216 if (wrap_offset && lmargin > 0 && lmargin < nleft)
1217 lmargin = nleft;
1218 }
1219 else
Jari Aaltob72432f1999-02-19 17:11:39 +00001220 lmargin = last_lmargin;
Jari Aalto726f6381996-08-26 18:22:31 +00001221
Chet Rameyac50fba2014-02-26 09:36:43 -05001222 displaying_prompt_first_line = lmargin < nleft;
1223
Jari Aalto726f6381996-08-26 18:22:31 +00001224 /* If the first character on the screen isn't the first character
1225 in the display line, indicate this with a special character. */
1226 if (lmargin > 0)
1227 line[lmargin] = '<';
1228
1229 /* If SCREENWIDTH characters starting at LMARGIN do not encompass
Jari Aaltob72432f1999-02-19 17:11:39 +00001230 the whole line, indicate that with a special character at the
1231 right edge of the screen. If LMARGIN is 0, we need to take the
1232 wrap offset into account. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001233 t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
Jari Aalto726f6381996-08-26 18:22:31 +00001234 if (t < out)
Jari Aaltob72432f1999-02-19 17:11:39 +00001235 line[t - 1] = '>';
Jari Aalto726f6381996-08-26 18:22:31 +00001236
Chet Ramey89a92862011-11-21 20:49:12 -05001237 if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
Jari Aalto726f6381996-08-26 18:22:31 +00001238 {
1239 forced_display = 0;
Chet Ramey89a92862011-11-21 20:49:12 -05001240 o_cpos = _rl_last_c_pos;
1241 cpos_adjusted = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001242 update_line (&visible_line[last_lmargin],
1243 &invisible_line[lmargin],
1244 0,
Jari Aalto28ef6c32001-04-06 19:14:31 +00001245 _rl_screenwidth + visible_wrap_offset,
1246 _rl_screenwidth + (lmargin ? 0 : wrap_offset),
Jari Aalto726f6381996-08-26 18:22:31 +00001247 0);
1248
Chet Rameyac50fba2014-02-26 09:36:43 -05001249 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1250 displaying_prompt_first_line && OLD_CPOS_IN_PROMPT())
Chet Ramey00018032011-11-21 20:51:19 -05001251 _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
Chet Ramey89a92862011-11-21 20:49:12 -05001252
Jari Aalto726f6381996-08-26 18:22:31 +00001253 /* If the visible new line is shorter than the old, but the number
1254 of invisible characters is greater, and we are at the end of
1255 the new line, we need to clear to eol. */
1256 t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
1257 if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
Chet Rameyac50fba2014-02-26 09:36:43 -05001258 (_rl_last_c_pos == out) && displaying_prompt_first_line &&
Jari Aalto726f6381996-08-26 18:22:31 +00001259 t < visible_first_line_len)
1260 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00001261 nleft = _rl_screenwidth - t;
Jari Aaltod166f041997-06-05 14:59:13 +00001262 _rl_clear_to_eol (nleft);
Jari Aalto726f6381996-08-26 18:22:31 +00001263 }
1264 visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001265 if (visible_first_line_len > _rl_screenwidth)
1266 visible_first_line_len = _rl_screenwidth;
Jari Aalto726f6381996-08-26 18:22:31 +00001267
Jari Aalto06285672006-10-10 14:15:34 +00001268 _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
Jari Aalto726f6381996-08-26 18:22:31 +00001269 last_lmargin = lmargin;
1270 }
1271 }
1272 fflush (rl_outstream);
1273
1274 /* Swap visible and non-visible lines. */
1275 {
Jari Aalto31859422009-01-12 13:36:28 +00001276 struct line_state *vtemp = line_state_visible;
Jari Aaltobb706242000-03-17 21:46:59 +00001277
Jari Aalto31859422009-01-12 13:36:28 +00001278 line_state_visible = line_state_invisible;
1279 line_state_invisible = vtemp;
Jari Aaltobb706242000-03-17 21:46:59 +00001280
Jari Aalto726f6381996-08-26 18:22:31 +00001281 rl_display_fixed = 0;
1282 /* If we are displaying on a single line, and last_lmargin is > 0, we
1283 are not displaying any invisible characters, so set visible_wrap_offset
1284 to 0. */
1285 if (_rl_horizontal_scroll_mode && last_lmargin)
1286 visible_wrap_offset = 0;
1287 else
1288 visible_wrap_offset = wrap_offset;
1289 }
Jari Aalto31859422009-01-12 13:36:28 +00001290
Chet Ramey89a92862011-11-21 20:49:12 -05001291 RL_UNSETSTATE (RL_STATE_REDISPLAYING);
Jari Aalto31859422009-01-12 13:36:28 +00001292 _rl_release_sigint ();
Jari Aalto726f6381996-08-26 18:22:31 +00001293}
1294
1295/* PWP: update_line() is based on finding the middle difference of each
1296 line on the screen; vis:
1297
1298 /old first difference
1299 /beginning of line | /old last same /old EOL
1300 v v v v
1301old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
1302new: eddie> Oh, my little buggy says to me, as lurgid as
1303 ^ ^ ^ ^
1304 \beginning of line | \new last same \new end of line
1305 \new first difference
1306
1307 All are character pointers for the sake of speed. Special cases for
Jari Aaltob72432f1999-02-19 17:11:39 +00001308 no differences, as well as for end of line additions must be handled.
Jari Aalto726f6381996-08-26 18:22:31 +00001309
1310 Could be made even smarter, but this works well enough */
1311static void
1312update_line (old, new, current_line, omax, nmax, inv_botlin)
1313 register char *old, *new;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001314 int current_line, omax, nmax, inv_botlin;
Jari Aalto726f6381996-08-26 18:22:31 +00001315{
1316 register char *ofd, *ols, *oe, *nfd, *nls, *ne;
Jari Aaltof1be6662008-11-18 13:15:12 +00001317 int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001318 int current_invis_chars;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001319 int col_lendiff, col_temp;
Chet Rameyac50fba2014-02-26 09:36:43 -05001320 int bytes_to_insert;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001321#if defined (HANDLE_MULTIBYTE)
1322 mbstate_t ps_new, ps_old;
Jari Aalto06285672006-10-10 14:15:34 +00001323 int new_offset, old_offset;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001324#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001325
1326 /* If we're at the right edge of a terminal that supports xn, we're
1327 ready to wrap around, so do so. This fixes problems with knowing
1328 the exact cursor position and cut-and-paste with certain terminal
1329 emulators. In this calculation, TEMP is the physical screen
1330 position of the cursor. */
Jari Aalto95732b42005-12-07 14:08:12 +00001331 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1332 temp = _rl_last_c_pos;
1333 else
Jari Aaltof1be6662008-11-18 13:15:12 +00001334 temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001335 if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
Jari Aalto7117c2d2002-07-17 14:10:11 +00001336 && _rl_last_v_pos == current_line - 1)
Jari Aalto726f6381996-08-26 18:22:31 +00001337 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001338#if defined (HANDLE_MULTIBYTE)
1339 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1340 {
1341 wchar_t wc;
1342 mbstate_t ps;
1343 int tempwidth, bytes;
1344 size_t ret;
1345
1346 /* This fixes only double-column characters, but if the wrapped
Chet Rameyac50fba2014-02-26 09:36:43 -05001347 character consumes more than three columns, spaces will be
Jari Aalto7117c2d2002-07-17 14:10:11 +00001348 inserted in the string buffer. */
Jari Aalto31859422009-01-12 13:36:28 +00001349 if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0)
1350 _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001351
1352 memset (&ps, 0, sizeof (mbstate_t));
1353 ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
Jari Aaltob80f6442004-07-27 13:29:18 +00001354 if (MB_INVALIDCH (ret))
Jari Aalto7117c2d2002-07-17 14:10:11 +00001355 {
1356 tempwidth = 1;
1357 ret = 1;
1358 }
Jari Aaltob80f6442004-07-27 13:29:18 +00001359 else if (MB_NULLWCH (ret))
Jari Aalto7117c2d2002-07-17 14:10:11 +00001360 tempwidth = 0;
1361 else
Chet Rameyac50fba2014-02-26 09:36:43 -05001362 tempwidth = WCWIDTH (wc);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001363
1364 if (tempwidth > 0)
1365 {
Chet Ramey00018032011-11-21 20:51:19 -05001366 int count, i;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001367 bytes = ret;
1368 for (count = 0; count < bytes; count++)
1369 putc (new[count], rl_outstream);
1370 _rl_last_c_pos = tempwidth;
1371 _rl_last_v_pos++;
1372 memset (&ps, 0, sizeof (mbstate_t));
1373 ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
1374 if (ret != 0 && bytes != 0)
1375 {
Jari Aaltob80f6442004-07-27 13:29:18 +00001376 if (MB_INVALIDCH (ret))
Chet Ramey00018032011-11-21 20:51:19 -05001377 ret = 1;
1378 memmove (old+bytes, old+ret, strlen (old+ret));
Jari Aalto7117c2d2002-07-17 14:10:11 +00001379 memcpy (old, new, bytes);
Chet Ramey00018032011-11-21 20:51:19 -05001380 /* Fix up indices if we copy data from one line to another */
1381 omax += bytes - ret;
Chet Rameyac50fba2014-02-26 09:36:43 -05001382 for (i = current_line+1; i <= inv_botlin+1; i++)
Chet Ramey00018032011-11-21 20:51:19 -05001383 vis_lbreaks[i] += bytes - ret;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001384 }
1385 }
1386 else
1387 {
1388 putc (' ', rl_outstream);
1389 _rl_last_c_pos = 1;
1390 _rl_last_v_pos++;
1391 if (old[0] && new[0])
1392 old[0] = new[0];
1393 }
1394 }
Jari Aalto726f6381996-08-26 18:22:31 +00001395 else
Jari Aalto7117c2d2002-07-17 14:10:11 +00001396#endif
1397 {
1398 if (new[0])
1399 putc (new[0], rl_outstream);
1400 else
1401 putc (' ', rl_outstream);
Jari Aalto95732b42005-12-07 14:08:12 +00001402 _rl_last_c_pos = 1;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001403 _rl_last_v_pos++;
1404 if (old[0] && new[0])
1405 old[0] = new[0];
1406 }
Jari Aalto726f6381996-08-26 18:22:31 +00001407 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001408
Jari Aalto726f6381996-08-26 18:22:31 +00001409
1410 /* Find first difference. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001411#if defined (HANDLE_MULTIBYTE)
1412 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1413 {
Jari Aaltob80f6442004-07-27 13:29:18 +00001414 /* See if the old line is a subset of the new line, so that the
1415 only change is adding characters. */
1416 temp = (omax < nmax) ? omax : nmax;
Jari Aalto31859422009-01-12 13:36:28 +00001417 if (memcmp (old, new, temp) == 0) /* adding at the end */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001418 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001419 new_offset = old_offset = temp;
Jari Aaltob80f6442004-07-27 13:29:18 +00001420 ofd = old + temp;
1421 nfd = new + temp;
1422 }
1423 else
1424 {
1425 memset (&ps_new, 0, sizeof(mbstate_t));
1426 memset (&ps_old, 0, sizeof(mbstate_t));
1427
1428 if (omax == nmax && STREQN (new, old, omax))
1429 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001430 old_offset = omax;
1431 new_offset = nmax;
Jari Aaltob80f6442004-07-27 13:29:18 +00001432 ofd = old + omax;
1433 nfd = new + nmax;
1434 }
1435 else
1436 {
1437 new_offset = old_offset = 0;
1438 for (ofd = old, nfd = new;
1439 (ofd - old < omax) && *ofd &&
1440 _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
1441 {
1442 old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
1443 new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
Chet Rameyac50fba2014-02-26 09:36:43 -05001444
Jari Aaltob80f6442004-07-27 13:29:18 +00001445 ofd = old + old_offset;
1446 nfd = new + new_offset;
1447 }
1448 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001449 }
1450 }
1451 else
1452#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001453 for (ofd = old, nfd = new;
1454 (ofd - old < omax) && *ofd && (*ofd == *nfd);
1455 ofd++, nfd++)
1456 ;
1457
1458 /* Move to the end of the screen line. ND and OD are used to keep track
1459 of the distance between ne and new and oe and old, respectively, to
1460 move a subtraction out of each loop. */
1461 for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
1462 for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
1463
1464 /* If no difference, continue to next line. */
1465 if (ofd == oe && nfd == ne)
1466 return;
1467
Chet Rameyac50fba2014-02-26 09:36:43 -05001468#if defined (HANDLE_MULTIBYTE)
1469 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_utf8locale)
1470 {
1471 wchar_t wc;
1472 mbstate_t ps = { 0 };
1473 int t;
1474
1475 /* If the first character in the difference is a zero-width character,
1476 assume it's a combining character and back one up so the two base
1477 characters no longer compare equivalently. */
1478 t = mbrtowc (&wc, ofd, MB_CUR_MAX, &ps);
1479 if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0)
1480 {
1481 old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY);
1482 new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY);
1483 ofd = old + old_offset; /* equal by definition */
1484 nfd = new + new_offset;
1485 }
1486 }
1487#endif
1488
Jari Aalto726f6381996-08-26 18:22:31 +00001489 wsatend = 1; /* flag for trailing whitespace */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001490
1491#if defined (HANDLE_MULTIBYTE)
1492 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1493 {
1494 ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
1495 nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
Chet Rameyac50fba2014-02-26 09:36:43 -05001496
Jari Aalto7117c2d2002-07-17 14:10:11 +00001497 while ((ols > ofd) && (nls > nfd))
1498 {
1499 memset (&ps_old, 0, sizeof (mbstate_t));
1500 memset (&ps_new, 0, sizeof (mbstate_t));
1501
Jari Aaltob80f6442004-07-27 13:29:18 +00001502#if 0
1503 /* On advice from jir@yamato.ibm.com */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001504 _rl_adjust_point (old, ols - old, &ps_old);
1505 _rl_adjust_point (new, nls - new, &ps_new);
Jari Aaltob80f6442004-07-27 13:29:18 +00001506#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +00001507
1508 if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
1509 break;
1510
1511 if (*ols == ' ')
1512 wsatend = 0;
1513
1514 ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
1515 nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
1516 }
1517 }
1518 else
1519 {
1520#endif /* HANDLE_MULTIBYTE */
Jari Aalto726f6381996-08-26 18:22:31 +00001521 ols = oe - 1; /* find last same */
1522 nls = ne - 1;
1523 while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
1524 {
1525 if (*ols != ' ')
1526 wsatend = 0;
1527 ols--;
1528 nls--;
1529 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001530#if defined (HANDLE_MULTIBYTE)
1531 }
1532#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001533
1534 if (wsatend)
1535 {
1536 ols = oe;
1537 nls = ne;
1538 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001539#if defined (HANDLE_MULTIBYTE)
1540 /* This may not work for stateful encoding, but who cares? To handle
1541 stateful encoding properly, we have to scan each string from the
1542 beginning and compare. */
1543 else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
1544#else
Jari Aalto726f6381996-08-26 18:22:31 +00001545 else if (*ols != *nls)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001546#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001547 {
1548 if (*ols) /* don't step past the NUL */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001549 {
1550 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1551 ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
1552 else
1553 ols++;
1554 }
Jari Aalto726f6381996-08-26 18:22:31 +00001555 if (*nls)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001556 {
1557 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1558 nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
1559 else
1560 nls++;
1561 }
Jari Aalto726f6381996-08-26 18:22:31 +00001562 }
1563
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001564 /* count of invisible characters in the current invisible line. */
1565 current_invis_chars = W_OFFSET (current_line, wrap_offset);
1566 if (_rl_last_v_pos != current_line)
1567 {
1568 _rl_move_vert (current_line);
Jari Aalto95732b42005-12-07 14:08:12 +00001569 if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001570 _rl_last_c_pos += visible_wrap_offset;
1571 }
Jari Aalto726f6381996-08-26 18:22:31 +00001572
1573 /* If this is the first line and there are invisible characters in the
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001574 prompt string, and the prompt string has not changed, and the current
1575 cursor position is before the last invisible character in the prompt,
1576 and the index of the character to move to is past the end of the prompt
1577 string, then redraw the entire prompt string. We can only do this
1578 reliably if the terminal supports a `cr' capability.
Jari Aalto726f6381996-08-26 18:22:31 +00001579
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001580 This is not an efficiency hack -- there is a problem with redrawing
1581 portions of the prompt string if they contain terminal escape
1582 sequences (like drawing the `unbold' sequence without a corresponding
1583 `bold') that manifests itself on certain terminals. */
Jari Aalto726f6381996-08-26 18:22:31 +00001584
Jari Aalto06285672006-10-10 14:15:34 +00001585 lendiff = local_prompt_len;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001586 od = ofd - old; /* index of first difference in visible line */
Jari Aalto726f6381996-08-26 18:22:31 +00001587 if (current_line == 0 && !_rl_horizontal_scroll_mode &&
Jari Aalto28ef6c32001-04-06 19:14:31 +00001588 _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
Jari Aalto06285672006-10-10 14:15:34 +00001589 od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
Jari Aalto726f6381996-08-26 18:22:31 +00001590 {
Jari Aaltobb706242000-03-17 21:46:59 +00001591#if defined (__MSDOS__)
1592 putc ('\r', rl_outstream);
1593#else
Jari Aalto28ef6c32001-04-06 19:14:31 +00001594 tputs (_rl_term_cr, 1, _rl_output_character_function);
Jari Aaltobb706242000-03-17 21:46:59 +00001595#endif
Jari Aalto31859422009-01-12 13:36:28 +00001596 if (modmark)
1597 _rl_output_some_chars ("*", 1);
Jari Aalto726f6381996-08-26 18:22:31 +00001598 _rl_output_some_chars (local_prompt, lendiff);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001599 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Jari Aalto95732b42005-12-07 14:08:12 +00001600 {
1601 /* We take wrap_offset into account here so we can pass correct
1602 information to _rl_move_cursor_relative. */
Chet Ramey00018032011-11-21 20:51:19 -05001603 _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
Jari Aalto95732b42005-12-07 14:08:12 +00001604 cpos_adjusted = 1;
1605 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001606 else
Jari Aalto31859422009-01-12 13:36:28 +00001607 _rl_last_c_pos = lendiff + modmark;
Jari Aalto726f6381996-08-26 18:22:31 +00001608 }
1609
Jari Aaltof1be6662008-11-18 13:15:12 +00001610 o_cpos = _rl_last_c_pos;
1611
Jari Aalto06285672006-10-10 14:15:34 +00001612 /* When this function returns, _rl_last_c_pos is correct, and an absolute
Chet Rameyac50fba2014-02-26 09:36:43 -05001613 cursor position in multibyte mode, but a buffer index when not in a
Jari Aalto06285672006-10-10 14:15:34 +00001614 multibyte locale. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001615 _rl_move_cursor_relative (od, old);
Chet Rameyac50fba2014-02-26 09:36:43 -05001616
Jari Aalto06285672006-10-10 14:15:34 +00001617#if defined (HANDLE_MULTIBYTE)
1618 /* We need to indicate that the cursor position is correct in the presence of
1619 invisible characters in the prompt string. Let's see if setting this when
1620 we make sure we're at the end of the drawn prompt string works. */
Jari Aalto31859422009-01-12 13:36:28 +00001621 if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
Jari Aaltof1be6662008-11-18 13:15:12 +00001622 (_rl_last_c_pos > 0 || o_cpos > 0) &&
1623 _rl_last_c_pos == prompt_physical_chars)
Jari Aalto06285672006-10-10 14:15:34 +00001624 cpos_adjusted = 1;
1625#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001626
Jari Aalto7117c2d2002-07-17 14:10:11 +00001627 /* if (len (new) > len (old))
Chet Rameyac50fba2014-02-26 09:36:43 -05001628 lendiff == difference in buffer (bytes)
1629 col_lendiff == difference on screen (columns)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001630 When not using multibyte characters, these are equal */
Jari Aalto726f6381996-08-26 18:22:31 +00001631 lendiff = (nls - nfd) - (ols - ofd);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001632 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Chet Ramey00018032011-11-21 20:51:19 -05001633 col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001634 else
1635 col_lendiff = lendiff;
Jari Aalto726f6381996-08-26 18:22:31 +00001636
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001637 /* If we are changing the number of invisible characters in a line, and
1638 the spot of first difference is before the end of the invisible chars,
1639 lendiff needs to be adjusted. */
Chet Rameyeec5e6e2014-05-16 14:17:38 -04001640 if (current_line == 0 && /* !_rl_horizontal_scroll_mode && */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001641 current_invis_chars != visible_wrap_offset)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001642 {
1643 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1644 {
1645 lendiff += visible_wrap_offset - current_invis_chars;
1646 col_lendiff += visible_wrap_offset - current_invis_chars;
1647 }
1648 else
1649 {
1650 lendiff += visible_wrap_offset - current_invis_chars;
1651 col_lendiff = lendiff;
1652 }
1653 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001654
Chet Rameyac50fba2014-02-26 09:36:43 -05001655 /* We use temp as a count of the number of bytes from the first difference
1656 to the end of the new line. col_temp is the corresponding number of
1657 screen columns. A `dumb' update moves to the spot of first difference
1658 and writes TEMP bytes. */
Jari Aalto726f6381996-08-26 18:22:31 +00001659 /* Insert (diff (len (old), len (new)) ch. */
1660 temp = ne - nfd;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001661 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Chet Ramey00018032011-11-21 20:51:19 -05001662 col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001663 else
1664 col_temp = temp;
1665
Chet Rameyac50fba2014-02-26 09:36:43 -05001666 /* how many bytes from the new line buffer to write to the display */
1667 bytes_to_insert = nls - nfd;
1668
1669 /* col_lendiff > 0 if we are adding characters to the line */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001670 if (col_lendiff > 0) /* XXX - was lendiff */
Jari Aalto726f6381996-08-26 18:22:31 +00001671 {
1672 /* Non-zero if we're increasing the number of lines. */
1673 int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
Jari Aaltof1be6662008-11-18 13:15:12 +00001674 /* If col_lendiff is > 0, implying that the new string takes up more
1675 screen real estate than the old, but lendiff is < 0, meaning that it
1676 takes fewer bytes, we need to just output the characters starting
1677 from the first difference. These will overwrite what is on the
1678 display, so there's no reason to do a smart update. This can really
1679 only happen in a multibyte environment. */
1680 if (lendiff < 0)
1681 {
1682 _rl_output_some_chars (nfd, temp);
Chet Rameyac50fba2014-02-26 09:36:43 -05001683 _rl_last_c_pos += col_temp; /* XXX - was _rl_col_width (nfd, 0, temp, 1); */
Jari Aaltof1be6662008-11-18 13:15:12 +00001684 /* If nfd begins before any invisible characters in the prompt,
1685 adjust _rl_last_c_pos to account for wrap_offset and set
1686 cpos_adjusted to let the caller know. */
Chet Rameyac50fba2014-02-26 09:36:43 -05001687 if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
Jari Aaltof1be6662008-11-18 13:15:12 +00001688 {
1689 _rl_last_c_pos -= wrap_offset;
1690 cpos_adjusted = 1;
1691 }
1692 return;
1693 }
Jari Aalto726f6381996-08-26 18:22:31 +00001694 /* Sometimes it is cheaper to print the characters rather than
1695 use the terminal's capabilities. If we're growing the number
1696 of lines, make sure we actually cause the new line to wrap
1697 around on auto-wrapping terminals. */
Jari Aaltof1be6662008-11-18 13:15:12 +00001698 else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
Jari Aalto726f6381996-08-26 18:22:31 +00001699 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00001700 /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
Jari Aalto726f6381996-08-26 18:22:31 +00001701 _rl_horizontal_scroll_mode == 1, inserting the characters with
Jari Aalto28ef6c32001-04-06 19:14:31 +00001702 _rl_term_IC or _rl_term_ic will screw up the screen because of the
Jari Aalto726f6381996-08-26 18:22:31 +00001703 invisible characters. We need to just draw them. */
Jari Aalto31859422009-01-12 13:36:28 +00001704 /* The same thing happens if we're trying to draw before the last
1705 invisible character in the prompt string or we're increasing the
1706 number of invisible characters in the line and we're not drawing
1707 the entire prompt string. */
1708 if (*ols && ((_rl_horizontal_scroll_mode &&
1709 _rl_last_c_pos == 0 &&
1710 lendiff > prompt_visible_length &&
1711 current_invis_chars > 0) == 0) &&
1712 (((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1713 current_line == 0 && wrap_offset &&
1714 ((nfd - new) <= prompt_last_invisible) &&
1715 (col_lendiff < prompt_visible_length)) == 0) &&
1716 (visible_wrap_offset >= current_invis_chars))
Jari Aalto726f6381996-08-26 18:22:31 +00001717 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001718 open_some_spaces (col_lendiff);
1719 _rl_output_some_chars (nfd, bytes_to_insert);
1720 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1721 _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
1722 else
1723 _rl_last_c_pos += bytes_to_insert;
Jari Aalto726f6381996-08-26 18:22:31 +00001724 }
Jari Aalto95732b42005-12-07 14:08:12 +00001725 else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001726 {
1727 /* At the end of a line the characters do not have to
1728 be "inserted". They can just be placed on the screen. */
Chet Rameyac50fba2014-02-26 09:36:43 -05001729 _rl_output_some_chars (nfd, temp);
1730 _rl_last_c_pos += col_temp;
1731 return;
Jari Aalto726f6381996-08-26 18:22:31 +00001732 }
Chet Rameyac50fba2014-02-26 09:36:43 -05001733 else /* just write from first difference to end of new line */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001734 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001735 _rl_output_some_chars (nfd, temp);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001736 _rl_last_c_pos += col_temp;
Jari Aalto31859422009-01-12 13:36:28 +00001737 /* If nfd begins before the last invisible character in the
1738 prompt, adjust _rl_last_c_pos to account for wrap_offset
1739 and set cpos_adjusted to let the caller know. */
Chet Rameyac50fba2014-02-26 09:36:43 -05001740 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
Jari Aaltof1be6662008-11-18 13:15:12 +00001741 {
1742 _rl_last_c_pos -= wrap_offset;
1743 cpos_adjusted = 1;
1744 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001745 return;
1746 }
Chet Rameyac50fba2014-02-26 09:36:43 -05001747
1748 if (bytes_to_insert > lendiff)
Jari Aalto726f6381996-08-26 18:22:31 +00001749 {
Jari Aalto31859422009-01-12 13:36:28 +00001750 /* If nfd begins before the last invisible character in the
1751 prompt, adjust _rl_last_c_pos to account for wrap_offset
1752 and set cpos_adjusted to let the caller know. */
Chet Rameyac50fba2014-02-26 09:36:43 -05001753 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
Jari Aalto31859422009-01-12 13:36:28 +00001754 {
1755 _rl_last_c_pos -= wrap_offset;
1756 cpos_adjusted = 1;
1757 }
Jari Aalto726f6381996-08-26 18:22:31 +00001758 }
1759 }
1760 else
1761 {
1762 /* cannot insert chars, write to EOL */
1763 _rl_output_some_chars (nfd, temp);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001764 _rl_last_c_pos += col_temp;
Jari Aalto95732b42005-12-07 14:08:12 +00001765 /* If we're in a multibyte locale and were before the last invisible
1766 char in the current line (which implies we just output some invisible
1767 characters) we need to adjust _rl_last_c_pos, since it represents
1768 a physical character position. */
Jari Aalto31859422009-01-12 13:36:28 +00001769 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1770 current_line == prompt_last_screen_line && wrap_offset &&
Chet Rameyac50fba2014-02-26 09:36:43 -05001771 displaying_prompt_first_line &&
Jari Aalto31859422009-01-12 13:36:28 +00001772 wrap_offset != prompt_invis_chars_first_line &&
1773 ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
1774 {
1775 _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
1776 cpos_adjusted = 1;
1777 }
Jari Aalto726f6381996-08-26 18:22:31 +00001778 }
1779 }
1780 else /* Delete characters from line. */
1781 {
1782 /* If possible and inexpensive to use terminal deletion, then do so. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001783 if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
Jari Aalto726f6381996-08-26 18:22:31 +00001784 {
1785 /* If all we're doing is erasing the invisible characters in the
1786 prompt string, don't bother. It screws up the assumptions
1787 about what's on the screen. */
1788 if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
Chet Rameyac50fba2014-02-26 09:36:43 -05001789 displaying_prompt_first_line &&
Jari Aalto726f6381996-08-26 18:22:31 +00001790 -lendiff == visible_wrap_offset)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001791 col_lendiff = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001792
Chet Rameyac50fba2014-02-26 09:36:43 -05001793 /* If we have moved lmargin and we're shrinking the line, we've
1794 already moved the cursor to the first character of the new line,
1795 so deleting -col_lendiff characters will mess up the cursor
1796 position calculation */
1797 if (_rl_horizontal_scroll_mode && displaying_prompt_first_line == 0 &&
1798 col_lendiff && _rl_last_c_pos < -col_lendiff)
1799 col_lendiff = 0;
1800
Jari Aalto7117c2d2002-07-17 14:10:11 +00001801 if (col_lendiff)
1802 delete_chars (-col_lendiff); /* delete (diff) characters */
Jari Aalto726f6381996-08-26 18:22:31 +00001803
Chet Rameyac50fba2014-02-26 09:36:43 -05001804 /* Copy (new) chars to screen from first diff to last match,
1805 overwriting what is there. */
1806 if (bytes_to_insert > 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001807 {
Jari Aaltof1be6662008-11-18 13:15:12 +00001808 /* If nfd begins at the prompt, or before the invisible
1809 characters in the prompt, we need to adjust _rl_last_c_pos
1810 in a multibyte locale to account for the wrap offset and
1811 set cpos_adjusted accordingly. */
Chet Rameyac50fba2014-02-26 09:36:43 -05001812 _rl_output_some_chars (nfd, bytes_to_insert);
Jari Aaltof1be6662008-11-18 13:15:12 +00001813 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1814 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001815 _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
1816 if (current_line == 0 && wrap_offset &&
1817 displaying_prompt_first_line &&
1818 _rl_last_c_pos > wrap_offset &&
1819 ((nfd - new) <= prompt_last_invisible))
Jari Aaltof1be6662008-11-18 13:15:12 +00001820 {
1821 _rl_last_c_pos -= wrap_offset;
1822 cpos_adjusted = 1;
1823 }
1824 }
Jari Aalto31859422009-01-12 13:36:28 +00001825 else
Chet Rameyac50fba2014-02-26 09:36:43 -05001826 _rl_last_c_pos += bytes_to_insert;
1827
Chet Rameyeec5e6e2014-05-16 14:17:38 -04001828 /* XXX - we only want to do this if we are at the end of the line
1829 so we move there with _rl_move_cursor_relative */
Chet Rameyac50fba2014-02-26 09:36:43 -05001830 if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new)))
Chet Rameyeec5e6e2014-05-16 14:17:38 -04001831 {
1832 _rl_move_cursor_relative (ne-new, new);
1833 goto clear_rest_of_line;
1834 }
Jari Aalto726f6381996-08-26 18:22:31 +00001835 }
1836 }
1837 /* Otherwise, print over the existing material. */
1838 else
1839 {
1840 if (temp > 0)
1841 {
Jari Aaltof1be6662008-11-18 13:15:12 +00001842 /* If nfd begins at the prompt, or before the invisible
1843 characters in the prompt, we need to adjust _rl_last_c_pos
1844 in a multibyte locale to account for the wrap offset and
1845 set cpos_adjusted accordingly. */
Jari Aalto726f6381996-08-26 18:22:31 +00001846 _rl_output_some_chars (nfd, temp);
Jari Aalto95732b42005-12-07 14:08:12 +00001847 _rl_last_c_pos += col_temp; /* XXX */
Jari Aaltof1be6662008-11-18 13:15:12 +00001848 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1849 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001850 if (current_line == 0 && wrap_offset &&
1851 displaying_prompt_first_line &&
1852 _rl_last_c_pos > wrap_offset &&
1853 ((nfd - new) <= prompt_last_invisible))
Jari Aaltof1be6662008-11-18 13:15:12 +00001854 {
1855 _rl_last_c_pos -= wrap_offset;
1856 cpos_adjusted = 1;
1857 }
1858 }
Jari Aalto726f6381996-08-26 18:22:31 +00001859 }
Chet Rameyac50fba2014-02-26 09:36:43 -05001860clear_rest_of_line:
Jari Aalto726f6381996-08-26 18:22:31 +00001861 lendiff = (oe - old) - (ne - new);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001862 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Chet Ramey00018032011-11-21 20:51:19 -05001863 col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001864 else
1865 col_lendiff = lendiff;
1866
Jari Aalto31859422009-01-12 13:36:28 +00001867 /* If we've already printed over the entire width of the screen,
1868 including the old material, then col_lendiff doesn't matter and
1869 space_to_eol will insert too many spaces. XXX - maybe we should
1870 adjust col_lendiff based on the difference between _rl_last_c_pos
1871 and _rl_screenwidth */
Chet Ramey89a92862011-11-21 20:49:12 -05001872 if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
Jari Aaltob72432f1999-02-19 17:11:39 +00001873 {
1874 if (_rl_term_autowrap && current_line < inv_botlin)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001875 space_to_eol (col_lendiff);
Jari Aaltob72432f1999-02-19 17:11:39 +00001876 else
Jari Aalto7117c2d2002-07-17 14:10:11 +00001877 _rl_clear_to_eol (col_lendiff);
Jari Aaltob72432f1999-02-19 17:11:39 +00001878 }
Jari Aalto726f6381996-08-26 18:22:31 +00001879 }
1880 }
1881}
1882
1883/* Tell the update routines that we have moved onto a new (empty) line. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001884int
Jari Aalto726f6381996-08-26 18:22:31 +00001885rl_on_new_line ()
1886{
1887 if (visible_line)
1888 visible_line[0] = '\0';
1889
1890 _rl_last_c_pos = _rl_last_v_pos = 0;
1891 _rl_vis_botlin = last_lmargin = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001892 if (vis_lbreaks)
1893 vis_lbreaks[0] = vis_lbreaks[1] = 0;
1894 visible_wrap_offset = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001895 return 0;
1896}
1897
Jari Aaltobb706242000-03-17 21:46:59 +00001898/* Tell the update routines that we have moved onto a new line with the
1899 prompt already displayed. Code originally from the version of readline
Jari Aaltob80f6442004-07-27 13:29:18 +00001900 distributed with CLISP. rl_expand_prompt must have already been called
1901 (explicitly or implicitly). This still doesn't work exactly right. */
Jari Aaltobb706242000-03-17 21:46:59 +00001902int
1903rl_on_new_line_with_prompt ()
1904{
1905 int prompt_size, i, l, real_screenwidth, newlines;
Jari Aaltob80f6442004-07-27 13:29:18 +00001906 char *prompt_last_line, *lprompt;
Jari Aaltobb706242000-03-17 21:46:59 +00001907
1908 /* Initialize visible_line and invisible_line to ensure that they can hold
1909 the already-displayed prompt. */
1910 prompt_size = strlen (rl_prompt) + 1;
1911 init_line_structures (prompt_size);
1912
1913 /* Make sure the line structures hold the already-displayed prompt for
1914 redisplay. */
Jari Aaltob80f6442004-07-27 13:29:18 +00001915 lprompt = local_prompt ? local_prompt : rl_prompt;
1916 strcpy (visible_line, lprompt);
1917 strcpy (invisible_line, lprompt);
Jari Aaltobb706242000-03-17 21:46:59 +00001918
1919 /* If the prompt contains newlines, take the last tail. */
1920 prompt_last_line = strrchr (rl_prompt, '\n');
1921 if (!prompt_last_line)
1922 prompt_last_line = rl_prompt;
1923
1924 l = strlen (prompt_last_line);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001925 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Chet Ramey00018032011-11-21 20:51:19 -05001926 _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1); /* XXX */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001927 else
1928 _rl_last_c_pos = l;
Jari Aaltobb706242000-03-17 21:46:59 +00001929
1930 /* Dissect prompt_last_line into screen lines. Note that here we have
1931 to use the real screenwidth. Readline's notion of screenwidth might be
1932 one less, see terminal.c. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001933 real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
Jari Aaltobb706242000-03-17 21:46:59 +00001934 _rl_last_v_pos = l / real_screenwidth;
1935 /* If the prompt length is a multiple of real_screenwidth, we don't know
1936 whether the cursor is at the end of the last line, or already at the
1937 beginning of the next line. Output a newline just to be safe. */
1938 if (l > 0 && (l % real_screenwidth) == 0)
1939 _rl_output_some_chars ("\n", 1);
1940 last_lmargin = 0;
1941
1942 newlines = 0; i = 0;
1943 while (i <= l)
1944 {
1945 _rl_vis_botlin = newlines;
1946 vis_lbreaks[newlines++] = i;
1947 i += real_screenwidth;
1948 }
1949 vis_lbreaks[newlines] = l;
1950 visible_wrap_offset = 0;
1951
Jari Aaltob80f6442004-07-27 13:29:18 +00001952 rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
1953
Jari Aaltobb706242000-03-17 21:46:59 +00001954 return 0;
1955}
1956
Jari Aalto726f6381996-08-26 18:22:31 +00001957/* Actually update the display, period. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001958int
Jari Aalto726f6381996-08-26 18:22:31 +00001959rl_forced_update_display ()
1960{
Jari Aalto06285672006-10-10 14:15:34 +00001961 register char *temp;
1962
Jari Aalto726f6381996-08-26 18:22:31 +00001963 if (visible_line)
1964 {
Jari Aalto06285672006-10-10 14:15:34 +00001965 temp = visible_line;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001966 while (*temp)
Jari Aaltob72432f1999-02-19 17:11:39 +00001967 *temp++ = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00001968 }
1969 rl_on_new_line ();
1970 forced_display++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001971 (*rl_redisplay_function) ();
Jari Aalto726f6381996-08-26 18:22:31 +00001972 return 0;
1973}
1974
1975/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
Jari Aalto95732b42005-12-07 14:08:12 +00001976 (Well, when we don't have multibyte characters, _rl_last_c_pos is a
1977 buffer index.)
Jari Aalto726f6381996-08-26 18:22:31 +00001978 DATA is the contents of the screen line of interest; i.e., where
1979 the movement is being done. */
1980void
1981_rl_move_cursor_relative (new, data)
1982 int new;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001983 const char *data;
Jari Aalto726f6381996-08-26 18:22:31 +00001984{
1985 register int i;
Jari Aalto95732b42005-12-07 14:08:12 +00001986 int woff; /* number of invisible chars on current line */
1987 int cpos, dpos; /* current and desired cursor positions */
Chet Ramey00018032011-11-21 20:51:19 -05001988 int adjust;
Jari Aalto726f6381996-08-26 18:22:31 +00001989
Jari Aaltof1be6662008-11-18 13:15:12 +00001990 woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
Jari Aalto95732b42005-12-07 14:08:12 +00001991 cpos = _rl_last_c_pos;
Chet Ramey89a92862011-11-21 20:49:12 -05001992
1993 if (cpos == 0 && cpos == new)
1994 return;
1995
Jari Aalto7117c2d2002-07-17 14:10:11 +00001996#if defined (HANDLE_MULTIBYTE)
1997 /* If we have multibyte characters, NEW is indexed by the buffer point in
1998 a multibyte string, but _rl_last_c_pos is the display position. In
Jari Aaltob80f6442004-07-27 13:29:18 +00001999 this case, NEW's display position is not obvious and must be
Jari Aalto95732b42005-12-07 14:08:12 +00002000 calculated. We need to account for invisible characters in this line,
2001 as long as we are past them and they are counted by _rl_col_width. */
2002 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +00002003 {
Chet Ramey00018032011-11-21 20:51:19 -05002004 adjust = 1;
2005 /* Try to short-circuit common cases and eliminate a bunch of multibyte
2006 character function calls. */
2007 /* 1. prompt string */
2008 if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
2009 {
2010 dpos = prompt_physical_chars;
2011 cpos_adjusted = 1;
2012 adjust = 0;
2013 }
2014 /* 2. prompt_string + line contents */
2015 else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0)
2016 {
2017 dpos = prompt_physical_chars + _rl_col_width (data, local_prompt_len, new, 1);
2018 cpos_adjusted = 1;
2019 adjust = 0;
2020 }
2021 else
2022 dpos = _rl_col_width (data, 0, new, 1);
2023
Chet Rameyac50fba2014-02-26 09:36:43 -05002024 if (displaying_prompt_first_line == 0)
2025 adjust = 0;
2026
Jari Aaltof1be6662008-11-18 13:15:12 +00002027 /* Use NEW when comparing against the last invisible character in the
2028 prompt string, since they're both buffer indices and DPOS is a
2029 desired display position. */
Chet Ramey00018032011-11-21 20:51:19 -05002030 if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */
Chet Ramey89a92862011-11-21 20:49:12 -05002031 (prompt_physical_chars >= _rl_screenwidth &&
Jari Aaltof1be6662008-11-18 13:15:12 +00002032 _rl_last_v_pos == prompt_last_screen_line &&
Chet Ramey89a92862011-11-21 20:49:12 -05002033 wrap_offset >= woff && dpos >= woff &&
Chet Ramey00018032011-11-21 20:51:19 -05002034 new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
Jari Aalto31859422009-01-12 13:36:28 +00002035 /* XXX last comparison might need to be >= */
Jari Aalto06285672006-10-10 14:15:34 +00002036 {
2037 dpos -= woff;
2038 /* Since this will be assigned to _rl_last_c_pos at the end (more
2039 precisely, _rl_last_c_pos == dpos when this function returns),
2040 let the caller know. */
2041 cpos_adjusted = 1;
2042 }
Jari Aaltob80f6442004-07-27 13:29:18 +00002043 }
Jari Aalto95732b42005-12-07 14:08:12 +00002044 else
Jari Aalto7117c2d2002-07-17 14:10:11 +00002045#endif
Jari Aalto95732b42005-12-07 14:08:12 +00002046 dpos = new;
2047
2048 /* If we don't have to do anything, then return. */
2049 if (cpos == dpos)
2050 return;
Jari Aalto726f6381996-08-26 18:22:31 +00002051
2052 /* It may be faster to output a CR, and then move forwards instead
2053 of moving backwards. */
2054 /* i == current physical cursor position. */
Jari Aalto95732b42005-12-07 14:08:12 +00002055#if defined (HANDLE_MULTIBYTE)
2056 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2057 i = _rl_last_c_pos;
2058 else
2059#endif
2060 i = _rl_last_c_pos - woff;
Jari Aalto06285672006-10-10 14:15:34 +00002061 if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
Jari Aalto28ef6c32001-04-06 19:14:31 +00002062 (_rl_term_autowrap && i == _rl_screenwidth))
Jari Aalto726f6381996-08-26 18:22:31 +00002063 {
2064#if defined (__MSDOS__)
2065 putc ('\r', rl_outstream);
2066#else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002067 tputs (_rl_term_cr, 1, _rl_output_character_function);
Jari Aalto726f6381996-08-26 18:22:31 +00002068#endif /* !__MSDOS__ */
Jari Aalto95732b42005-12-07 14:08:12 +00002069 cpos = _rl_last_c_pos = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002070 }
2071
Jari Aalto95732b42005-12-07 14:08:12 +00002072 if (cpos < dpos)
Jari Aalto726f6381996-08-26 18:22:31 +00002073 {
2074 /* Move the cursor forward. We do it by printing the command
2075 to move the cursor forward if there is one, else print that
2076 portion of the output buffer again. Which is cheaper? */
2077
2078 /* The above comment is left here for posterity. It is faster
2079 to print one character (non-control) than to print a control
2080 sequence telling the terminal to move forward one character.
2081 That kind of control is for people who don't know what the
2082 data is underneath the cursor. */
Jari Aalto06285672006-10-10 14:15:34 +00002083
2084 /* However, we need a handle on where the current display position is
2085 in the buffer for the immediately preceding comment to be true.
2086 In multibyte locales, we don't currently have that info available.
2087 Without it, we don't know where the data we have to display begins
2088 in the buffer and we have to go back to the beginning of the screen
2089 line. In this case, we can use the terminal sequence to move forward
2090 if it's available. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002091 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2092 {
Jari Aalto06285672006-10-10 14:15:34 +00002093 if (_rl_term_forward_char)
2094 {
2095 for (i = cpos; i < dpos; i++)
2096 tputs (_rl_term_forward_char, 1, _rl_output_character_function);
2097 }
2098 else
2099 {
2100 tputs (_rl_term_cr, 1, _rl_output_character_function);
2101 for (i = 0; i < new; i++)
2102 putc (data[i], rl_outstream);
2103 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00002104 }
2105 else
Jari Aalto95732b42005-12-07 14:08:12 +00002106 for (i = cpos; i < new; i++)
Jari Aalto7117c2d2002-07-17 14:10:11 +00002107 putc (data[i], rl_outstream);
Jari Aalto726f6381996-08-26 18:22:31 +00002108 }
Jari Aalto95732b42005-12-07 14:08:12 +00002109
Jari Aalto7117c2d2002-07-17 14:10:11 +00002110#if defined (HANDLE_MULTIBYTE)
2111 /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
2112 The byte length of the string is probably bigger than the column width
2113 of the string, which means that if NEW == _rl_last_c_pos, then NEW's
2114 display point is less than _rl_last_c_pos. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002115#endif
Jari Aalto95732b42005-12-07 14:08:12 +00002116 else if (cpos > dpos)
2117 _rl_backspace (cpos - dpos);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002118
Jari Aalto95732b42005-12-07 14:08:12 +00002119 _rl_last_c_pos = dpos;
Jari Aalto726f6381996-08-26 18:22:31 +00002120}
2121
2122/* PWP: move the cursor up or down. */
2123void
2124_rl_move_vert (to)
2125 int to;
2126{
2127 register int delta, i;
2128
Jari Aalto28ef6c32001-04-06 19:14:31 +00002129 if (_rl_last_v_pos == to || to > _rl_screenheight)
Jari Aalto726f6381996-08-26 18:22:31 +00002130 return;
2131
Jari Aalto726f6381996-08-26 18:22:31 +00002132 if ((delta = to - _rl_last_v_pos) > 0)
2133 {
2134 for (i = 0; i < delta; i++)
2135 putc ('\n', rl_outstream);
Jari Aaltobb706242000-03-17 21:46:59 +00002136#if defined (__MSDOS__)
2137 putc ('\r', rl_outstream);
2138#else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002139 tputs (_rl_term_cr, 1, _rl_output_character_function);
Jari Aaltobb706242000-03-17 21:46:59 +00002140#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002141 _rl_last_c_pos = 0;
2142 }
2143 else
2144 { /* delta < 0 */
Chet Rameyac50fba2014-02-26 09:36:43 -05002145#ifdef __DJGPP__
2146 int row, col;
2147
2148 fflush (rl_outstream);
2149 ScreenGetCursor (&row, &col);
2150 ScreenSetCursor (row + delta, col);
2151 i = -delta;
2152#else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002153 if (_rl_term_up && *_rl_term_up)
Jari Aalto726f6381996-08-26 18:22:31 +00002154 for (i = 0; i < -delta; i++)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002155 tputs (_rl_term_up, 1, _rl_output_character_function);
Chet Rameyac50fba2014-02-26 09:36:43 -05002156#endif /* !__DJGPP__ */
Jari Aalto726f6381996-08-26 18:22:31 +00002157 }
Jari Aaltobb706242000-03-17 21:46:59 +00002158
Jari Aalto726f6381996-08-26 18:22:31 +00002159 _rl_last_v_pos = to; /* Now TO is here */
2160}
2161
2162/* Physically print C on rl_outstream. This is for functions which know
2163 how to optimize the display. Return the number of characters output. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002164int
Jari Aalto726f6381996-08-26 18:22:31 +00002165rl_show_char (c)
2166 int c;
2167{
2168 int n = 1;
2169 if (META_CHAR (c) && (_rl_output_meta_chars == 0))
2170 {
2171 fprintf (rl_outstream, "M-");
2172 n += 2;
2173 c = UNMETA (c);
2174 }
2175
2176#if defined (DISPLAY_TABS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002177 if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
Jari Aalto726f6381996-08-26 18:22:31 +00002178#else
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002179 if (CTRL_CHAR (c) || c == RUBOUT)
Jari Aalto726f6381996-08-26 18:22:31 +00002180#endif /* !DISPLAY_TABS */
2181 {
2182 fprintf (rl_outstream, "C-");
2183 n += 2;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002184 c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
Jari Aalto726f6381996-08-26 18:22:31 +00002185 }
2186
2187 putc (c, rl_outstream);
2188 fflush (rl_outstream);
2189 return n;
2190}
2191
2192int
2193rl_character_len (c, pos)
2194 register int c, pos;
2195{
2196 unsigned char uc;
2197
2198 uc = (unsigned char)c;
2199
2200 if (META_CHAR (uc))
2201 return ((_rl_output_meta_chars == 0) ? 4 : 1);
2202
2203 if (uc == '\t')
2204 {
2205#if defined (DISPLAY_TABS)
2206 return (((pos | 7) + 1) - pos);
2207#else
2208 return (2);
2209#endif /* !DISPLAY_TABS */
2210 }
2211
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002212 if (CTRL_CHAR (c) || c == RUBOUT)
2213 return (2);
2214
Jari Aaltof73dda02001-11-13 17:56:06 +00002215 return ((ISPRINT (uc)) ? 1 : 2);
Jari Aalto726f6381996-08-26 18:22:31 +00002216}
Jari Aalto726f6381996-08-26 18:22:31 +00002217/* How to print things in the "echo-area". The prompt is treated as a
2218 mini-modeline. */
Jari Aalto95732b42005-12-07 14:08:12 +00002219static int msg_saved_prompt = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002220
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002221#if defined (USE_VARARGS)
2222int
2223#if defined (PREFER_STDARG)
2224rl_message (const char *format, ...)
2225#else
Jari Aalto726f6381996-08-26 18:22:31 +00002226rl_message (va_alist)
2227 va_dcl
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002228#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002229{
Jari Aalto726f6381996-08-26 18:22:31 +00002230 va_list args;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002231#if defined (PREFER_VARARGS)
2232 char *format;
2233#endif
Chet Rameyac50fba2014-02-26 09:36:43 -05002234#if defined (HAVE_VSNPRINTF)
2235 int bneed;
2236#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002237
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002238#if defined (PREFER_STDARG)
2239 va_start (args, format);
2240#else
Jari Aalto726f6381996-08-26 18:22:31 +00002241 va_start (args);
2242 format = va_arg (args, char *);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002243#endif
2244
Chet Rameyac50fba2014-02-26 09:36:43 -05002245 if (msg_buf == 0)
2246 msg_buf = xmalloc (msg_bufsiz = 128);
2247
Jari Aaltof73dda02001-11-13 17:56:06 +00002248#if defined (HAVE_VSNPRINTF)
Chet Rameyac50fba2014-02-26 09:36:43 -05002249 bneed = vsnprintf (msg_buf, msg_bufsiz - 1, format, args);
2250 if (bneed >= msg_bufsiz - 1)
2251 {
2252 msg_bufsiz = bneed + 1;
2253 msg_buf = xrealloc (msg_buf, msg_bufsiz);
2254 va_end (args);
2255
2256#if defined (PREFER_STDARG)
2257 va_start (args, format);
2258#else
2259 va_start (args);
2260 format = va_arg (args, char *);
2261#endif
2262 vsnprintf (msg_buf, msg_bufsiz - 1, format, args);
2263 }
Jari Aaltof73dda02001-11-13 17:56:06 +00002264#else
Jari Aalto726f6381996-08-26 18:22:31 +00002265 vsprintf (msg_buf, format, args);
Chet Rameyac50fba2014-02-26 09:36:43 -05002266 msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */
Jari Aaltof73dda02001-11-13 17:56:06 +00002267#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002268 va_end (args);
2269
Jari Aalto95732b42005-12-07 14:08:12 +00002270 if (saved_local_prompt == 0)
2271 {
2272 rl_save_prompt ();
2273 msg_saved_prompt = 1;
2274 }
Chet Rameyac50fba2014-02-26 09:36:43 -05002275 else if (local_prompt != saved_local_prompt)
2276 {
2277 FREE (local_prompt);
2278 FREE (local_prompt_prefix);
2279 local_prompt = (char *)NULL;
2280 }
Jari Aalto726f6381996-08-26 18:22:31 +00002281 rl_display_prompt = msg_buf;
Jari Aalto95732b42005-12-07 14:08:12 +00002282 local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
2283 &prompt_last_invisible,
2284 &prompt_invis_chars_first_line,
2285 &prompt_physical_chars);
2286 local_prompt_prefix = (char *)NULL;
Jari Aalto06285672006-10-10 14:15:34 +00002287 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002288 (*rl_redisplay_function) ();
Jari Aalto95732b42005-12-07 14:08:12 +00002289
Jari Aalto726f6381996-08-26 18:22:31 +00002290 return 0;
2291}
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002292#else /* !USE_VARARGS */
2293int
Jari Aalto726f6381996-08-26 18:22:31 +00002294rl_message (format, arg1, arg2)
2295 char *format;
2296{
Chet Rameyac50fba2014-02-26 09:36:43 -05002297 if (msg_buf == 0)
2298 msg_buf = xmalloc (msg_bufsiz = 128);
2299
Jari Aalto726f6381996-08-26 18:22:31 +00002300 sprintf (msg_buf, format, arg1, arg2);
Chet Rameyac50fba2014-02-26 09:36:43 -05002301 msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */
Jari Aalto95732b42005-12-07 14:08:12 +00002302
Jari Aalto726f6381996-08-26 18:22:31 +00002303 rl_display_prompt = msg_buf;
Jari Aalto95732b42005-12-07 14:08:12 +00002304 if (saved_local_prompt == 0)
2305 {
2306 rl_save_prompt ();
2307 msg_saved_prompt = 1;
2308 }
Chet Rameyac50fba2014-02-26 09:36:43 -05002309 else if (local_prompt != saved_local_prompt)
2310 {
2311 FREE (local_prompt);
2312 FREE (local_prompt_prefix);
2313 local_prompt = (char *)NULL;
2314 }
Jari Aalto95732b42005-12-07 14:08:12 +00002315 local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
2316 &prompt_last_invisible,
2317 &prompt_invis_chars_first_line,
2318 &prompt_physical_chars);
2319 local_prompt_prefix = (char *)NULL;
Jari Aalto06285672006-10-10 14:15:34 +00002320 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002321 (*rl_redisplay_function) ();
Jari Aalto95732b42005-12-07 14:08:12 +00002322
Jari Aalto726f6381996-08-26 18:22:31 +00002323 return 0;
2324}
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002325#endif /* !USE_VARARGS */
Jari Aalto726f6381996-08-26 18:22:31 +00002326
2327/* How to clear things from the "echo-area". */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002328int
Jari Aalto726f6381996-08-26 18:22:31 +00002329rl_clear_message ()
2330{
2331 rl_display_prompt = rl_prompt;
Jari Aalto95732b42005-12-07 14:08:12 +00002332 if (msg_saved_prompt)
2333 {
2334 rl_restore_prompt ();
2335 msg_saved_prompt = 0;
2336 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002337 (*rl_redisplay_function) ();
Jari Aalto726f6381996-08-26 18:22:31 +00002338 return 0;
2339}
2340
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002341int
Jari Aalto726f6381996-08-26 18:22:31 +00002342rl_reset_line_state ()
2343{
2344 rl_on_new_line ();
2345
2346 rl_display_prompt = rl_prompt ? rl_prompt : "";
2347 forced_display = 1;
2348 return 0;
2349}
2350
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002351void
Jari Aaltob72432f1999-02-19 17:11:39 +00002352rl_save_prompt ()
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002353{
2354 saved_local_prompt = local_prompt;
2355 saved_local_prefix = local_prompt_prefix;
Jari Aalto95732b42005-12-07 14:08:12 +00002356 saved_prefix_length = prompt_prefix_length;
Jari Aalto06285672006-10-10 14:15:34 +00002357 saved_local_length = local_prompt_len;
Jari Aalto28ef6c32001-04-06 19:14:31 +00002358 saved_last_invisible = prompt_last_invisible;
2359 saved_visible_length = prompt_visible_length;
Jari Aaltob80f6442004-07-27 13:29:18 +00002360 saved_invis_chars_first_line = prompt_invis_chars_first_line;
2361 saved_physical_chars = prompt_physical_chars;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002362
2363 local_prompt = local_prompt_prefix = (char *)0;
Jari Aalto06285672006-10-10 14:15:34 +00002364 local_prompt_len = 0;
Jari Aalto95732b42005-12-07 14:08:12 +00002365 prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
Jari Aaltob80f6442004-07-27 13:29:18 +00002366 prompt_invis_chars_first_line = prompt_physical_chars = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002367}
2368
2369void
Jari Aaltob72432f1999-02-19 17:11:39 +00002370rl_restore_prompt ()
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002371{
Jari Aalto28ef6c32001-04-06 19:14:31 +00002372 FREE (local_prompt);
2373 FREE (local_prompt_prefix);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002374
2375 local_prompt = saved_local_prompt;
2376 local_prompt_prefix = saved_local_prefix;
Jari Aalto06285672006-10-10 14:15:34 +00002377 local_prompt_len = saved_local_length;
Jari Aalto95732b42005-12-07 14:08:12 +00002378 prompt_prefix_length = saved_prefix_length;
Jari Aalto28ef6c32001-04-06 19:14:31 +00002379 prompt_last_invisible = saved_last_invisible;
2380 prompt_visible_length = saved_visible_length;
Jari Aaltob80f6442004-07-27 13:29:18 +00002381 prompt_invis_chars_first_line = saved_invis_chars_first_line;
2382 prompt_physical_chars = saved_physical_chars;
Jari Aalto95732b42005-12-07 14:08:12 +00002383
2384 /* can test saved_local_prompt to see if prompt info has been saved. */
2385 saved_local_prompt = saved_local_prefix = (char *)0;
Jari Aalto06285672006-10-10 14:15:34 +00002386 saved_local_length = 0;
Jari Aalto95732b42005-12-07 14:08:12 +00002387 saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
2388 saved_invis_chars_first_line = saved_physical_chars = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002389}
2390
2391char *
2392_rl_make_prompt_for_search (pchar)
2393 int pchar;
2394{
2395 int len;
Jari Aalto06285672006-10-10 14:15:34 +00002396 char *pmt, *p;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002397
Jari Aaltob72432f1999-02-19 17:11:39 +00002398 rl_save_prompt ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002399
Jari Aalto06285672006-10-10 14:15:34 +00002400 /* We've saved the prompt, and can do anything with the various prompt
2401 strings we need before they're restored. We want the unexpanded
2402 portion of the prompt string after any final newline. */
2403 p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
2404 if (p == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002405 {
2406 len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
Jari Aaltof73dda02001-11-13 17:56:06 +00002407 pmt = (char *)xmalloc (len + 2);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002408 if (len)
Jari Aaltob72432f1999-02-19 17:11:39 +00002409 strcpy (pmt, rl_prompt);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002410 pmt[len] = pchar;
2411 pmt[len+1] = '\0';
2412 }
2413 else
2414 {
Jari Aalto06285672006-10-10 14:15:34 +00002415 p++;
2416 len = strlen (p);
Jari Aaltof73dda02001-11-13 17:56:06 +00002417 pmt = (char *)xmalloc (len + 2);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002418 if (len)
Jari Aalto06285672006-10-10 14:15:34 +00002419 strcpy (pmt, p);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002420 pmt[len] = pchar;
2421 pmt[len+1] = '\0';
Jari Aalto06285672006-10-10 14:15:34 +00002422 }
Jari Aaltob80f6442004-07-27 13:29:18 +00002423
Jari Aalto06285672006-10-10 14:15:34 +00002424 /* will be overwritten by expand_prompt, called from rl_message */
Jari Aalto95732b42005-12-07 14:08:12 +00002425 prompt_physical_chars = saved_physical_chars + 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002426 return pmt;
2427}
2428
Jari Aalto726f6381996-08-26 18:22:31 +00002429/* Quick redisplay hack when erasing characters at the end of the line. */
2430void
2431_rl_erase_at_end_of_line (l)
2432 int l;
2433{
2434 register int i;
2435
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002436 _rl_backspace (l);
Jari Aalto726f6381996-08-26 18:22:31 +00002437 for (i = 0; i < l; i++)
2438 putc (' ', rl_outstream);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002439 _rl_backspace (l);
Jari Aalto726f6381996-08-26 18:22:31 +00002440 for (i = 0; i < l; i++)
2441 visible_line[--_rl_last_c_pos] = '\0';
2442 rl_display_fixed++;
2443}
2444
2445/* Clear to the end of the line. COUNT is the minimum
2446 number of character spaces to clear, */
Jari Aaltod166f041997-06-05 14:59:13 +00002447void
2448_rl_clear_to_eol (count)
Jari Aalto726f6381996-08-26 18:22:31 +00002449 int count;
2450{
Chet Rameyac50fba2014-02-26 09:36:43 -05002451#ifndef __MSDOS__
Jari Aalto28ef6c32001-04-06 19:14:31 +00002452 if (_rl_term_clreol)
2453 tputs (_rl_term_clreol, 1, _rl_output_character_function);
Chet Rameyac50fba2014-02-26 09:36:43 -05002454 else
2455#endif
2456 if (count)
2457 space_to_eol (count);
Jari Aalto726f6381996-08-26 18:22:31 +00002458}
2459
2460/* Clear to the end of the line using spaces. COUNT is the minimum
2461 number of character spaces to clear, */
2462static void
2463space_to_eol (count)
2464 int count;
2465{
2466 register int i;
2467
2468 for (i = 0; i < count; i++)
2469 putc (' ', rl_outstream);
2470
2471 _rl_last_c_pos += count;
2472}
2473
Jari Aaltod166f041997-06-05 14:59:13 +00002474void
2475_rl_clear_screen ()
2476{
Chet Rameyac50fba2014-02-26 09:36:43 -05002477#ifndef __DJGPP__
Jari Aalto28ef6c32001-04-06 19:14:31 +00002478 if (_rl_term_clrpag)
2479 tputs (_rl_term_clrpag, 1, _rl_output_character_function);
Jari Aaltod166f041997-06-05 14:59:13 +00002480 else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002481 rl_crlf ();
Chet Rameyac50fba2014-02-26 09:36:43 -05002482#else
2483 ScreenClear ();
2484 ScreenSetCursor (0, 0);
2485#endif /* __DJGPP__ */
Jari Aaltod166f041997-06-05 14:59:13 +00002486}
2487
Jari Aalto7117c2d2002-07-17 14:10:11 +00002488/* Insert COUNT characters from STRING to the output stream at column COL. */
Jari Aalto726f6381996-08-26 18:22:31 +00002489static void
Jari Aalto7117c2d2002-07-17 14:10:11 +00002490insert_some_chars (string, count, col)
Jari Aalto726f6381996-08-26 18:22:31 +00002491 char *string;
Jari Aalto7117c2d2002-07-17 14:10:11 +00002492 int count, col;
Jari Aalto726f6381996-08-26 18:22:31 +00002493{
Chet Rameyac50fba2014-02-26 09:36:43 -05002494 open_some_spaces (col);
Jari Aalto95732b42005-12-07 14:08:12 +00002495 _rl_output_some_chars (string, count);
Chet Rameyac50fba2014-02-26 09:36:43 -05002496}
2497
2498/* Insert COL spaces, keeping the cursor at the same position. We follow the
2499 ncurses documentation and use either im/ei with explicit spaces, or IC/ic
2500 by itself. We assume there will either be ei or we don't need to use it. */
2501static void
2502open_some_spaces (col)
2503 int col;
2504{
2505#if !defined (__MSDOS__) && !defined (__MINGW32__)
2506 char *buffer;
2507 register int i;
Jari Aalto7117c2d2002-07-17 14:10:11 +00002508
Jari Aalto726f6381996-08-26 18:22:31 +00002509 /* If IC is defined, then we do not have to "enter" insert mode. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00002510 if (_rl_term_IC)
Jari Aalto726f6381996-08-26 18:22:31 +00002511 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00002512 buffer = tgoto (_rl_term_IC, 0, col);
Jari Aalto726f6381996-08-26 18:22:31 +00002513 tputs (buffer, 1, _rl_output_character_function);
Jari Aalto726f6381996-08-26 18:22:31 +00002514 }
Chet Rameyac50fba2014-02-26 09:36:43 -05002515 else if (_rl_term_im && *_rl_term_im)
Jari Aalto726f6381996-08-26 18:22:31 +00002516 {
Chet Rameyac50fba2014-02-26 09:36:43 -05002517 tputs (_rl_term_im, 1, _rl_output_character_function);
2518 /* just output the desired number of spaces */
2519 for (i = col; i--; )
2520 _rl_output_character_function (' ');
2521 /* If there is a string to turn off insert mode, use it now. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00002522 if (_rl_term_ei && *_rl_term_ei)
2523 tputs (_rl_term_ei, 1, _rl_output_character_function);
Chet Rameyac50fba2014-02-26 09:36:43 -05002524 /* and move back the right number of spaces */
2525 _rl_backspace (col);
Jari Aalto726f6381996-08-26 18:22:31 +00002526 }
Chet Rameyac50fba2014-02-26 09:36:43 -05002527 else if (_rl_term_ic && *_rl_term_ic)
2528 {
2529 /* If there is a special command for inserting characters, then
2530 use that first to open up the space. */
2531 for (i = col; i--; )
2532 tputs (_rl_term_ic, 1, _rl_output_character_function);
2533 }
2534#endif /* !__MSDOS__ && !__MINGW32__ */
Jari Aalto726f6381996-08-26 18:22:31 +00002535}
2536
2537/* Delete COUNT characters from the display line. */
2538static void
2539delete_chars (count)
2540 int count;
2541{
Jari Aalto28ef6c32001-04-06 19:14:31 +00002542 if (count > _rl_screenwidth) /* XXX */
Jari Aalto726f6381996-08-26 18:22:31 +00002543 return;
2544
Jari Aalto95732b42005-12-07 14:08:12 +00002545#if !defined (__MSDOS__) && !defined (__MINGW32__)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002546 if (_rl_term_DC && *_rl_term_DC)
Jari Aalto726f6381996-08-26 18:22:31 +00002547 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002548 char *buffer;
Jari Aalto28ef6c32001-04-06 19:14:31 +00002549 buffer = tgoto (_rl_term_DC, count, count);
Jari Aalto726f6381996-08-26 18:22:31 +00002550 tputs (buffer, count, _rl_output_character_function);
2551 }
2552 else
2553 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00002554 if (_rl_term_dc && *_rl_term_dc)
Jari Aalto726f6381996-08-26 18:22:31 +00002555 while (count--)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002556 tputs (_rl_term_dc, 1, _rl_output_character_function);
Jari Aalto726f6381996-08-26 18:22:31 +00002557 }
Jari Aalto95732b42005-12-07 14:08:12 +00002558#endif /* !__MSDOS__ && !__MINGW32__ */
Jari Aalto726f6381996-08-26 18:22:31 +00002559}
2560
2561void
2562_rl_update_final ()
2563{
2564 int full_lines;
2565
2566 full_lines = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002567 /* If the cursor is the only thing on an otherwise-blank last line,
2568 compensate so we don't print an extra CRLF. */
2569 if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
Jari Aaltod166f041997-06-05 14:59:13 +00002570 visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00002571 {
2572 _rl_vis_botlin--;
2573 full_lines = 1;
2574 }
2575 _rl_move_vert (_rl_vis_botlin);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002576 /* If we've wrapped lines, remove the final xterm line-wrap flag. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00002577 if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
Jari Aalto726f6381996-08-26 18:22:31 +00002578 {
Jari Aalto726f6381996-08-26 18:22:31 +00002579 char *last_line;
Jari Aalto7117c2d2002-07-17 14:10:11 +00002580
Jari Aaltobb706242000-03-17 21:46:59 +00002581 last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
Jari Aalto06285672006-10-10 14:15:34 +00002582 cpos_buffer_position = -1; /* don't know where we are in buffer */
2583 _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */
Jari Aaltod166f041997-06-05 14:59:13 +00002584 _rl_clear_to_eol (0);
Jari Aalto28ef6c32001-04-06 19:14:31 +00002585 putc (last_line[_rl_screenwidth - 1], rl_outstream);
Jari Aalto726f6381996-08-26 18:22:31 +00002586 }
2587 _rl_vis_botlin = 0;
Jari Aalto28ef6c32001-04-06 19:14:31 +00002588 rl_crlf ();
Jari Aalto726f6381996-08-26 18:22:31 +00002589 fflush (rl_outstream);
2590 rl_display_fixed++;
2591}
2592
2593/* Move to the start of the current line. */
2594static void
2595cr ()
2596{
Jari Aalto28ef6c32001-04-06 19:14:31 +00002597 if (_rl_term_cr)
Jari Aalto726f6381996-08-26 18:22:31 +00002598 {
Jari Aaltobb706242000-03-17 21:46:59 +00002599#if defined (__MSDOS__)
2600 putc ('\r', rl_outstream);
2601#else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002602 tputs (_rl_term_cr, 1, _rl_output_character_function);
Jari Aaltobb706242000-03-17 21:46:59 +00002603#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002604 _rl_last_c_pos = 0;
2605 }
2606}
2607
Jari Aaltobb706242000-03-17 21:46:59 +00002608/* Redraw the last line of a multi-line prompt that may possibly contain
2609 terminal escape sequences. Called with the cursor at column 0 of the
2610 line to draw the prompt on. */
2611static void
2612redraw_prompt (t)
2613 char *t;
2614{
Jari Aalto95732b42005-12-07 14:08:12 +00002615 char *oldp;
Jari Aaltobb706242000-03-17 21:46:59 +00002616
Jari Aaltobb706242000-03-17 21:46:59 +00002617 oldp = rl_display_prompt;
Jari Aalto95732b42005-12-07 14:08:12 +00002618 rl_save_prompt ();
Jari Aaltobb706242000-03-17 21:46:59 +00002619
2620 rl_display_prompt = t;
Jari Aalto28ef6c32001-04-06 19:14:31 +00002621 local_prompt = expand_prompt (t, &prompt_visible_length,
2622 &prompt_last_invisible,
Jari Aaltob80f6442004-07-27 13:29:18 +00002623 &prompt_invis_chars_first_line,
2624 &prompt_physical_chars);
Jari Aaltobb706242000-03-17 21:46:59 +00002625 local_prompt_prefix = (char *)NULL;
Jari Aalto06285672006-10-10 14:15:34 +00002626 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
Jari Aalto95732b42005-12-07 14:08:12 +00002627
Jari Aaltobb706242000-03-17 21:46:59 +00002628 rl_forced_update_display ();
2629
2630 rl_display_prompt = oldp;
Jari Aalto95732b42005-12-07 14:08:12 +00002631 rl_restore_prompt();
Jari Aaltobb706242000-03-17 21:46:59 +00002632}
2633
Jari Aalto726f6381996-08-26 18:22:31 +00002634/* Redisplay the current line after a SIGWINCH is received. */
2635void
2636_rl_redisplay_after_sigwinch ()
2637{
Jari Aaltobb706242000-03-17 21:46:59 +00002638 char *t;
Jari Aalto726f6381996-08-26 18:22:31 +00002639
Jari Aalto31859422009-01-12 13:36:28 +00002640 /* Clear the last line (assuming that the screen size change will result in
2641 either more or fewer characters on that line only) and put the cursor at
2642 column 0. Make sure the right thing happens if we have wrapped to a new
2643 screen line. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00002644 if (_rl_term_cr)
Jari Aalto726f6381996-08-26 18:22:31 +00002645 {
Jari Aalto31859422009-01-12 13:36:28 +00002646 _rl_move_vert (_rl_vis_botlin);
2647
Jari Aaltobb706242000-03-17 21:46:59 +00002648#if defined (__MSDOS__)
2649 putc ('\r', rl_outstream);
2650#else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002651 tputs (_rl_term_cr, 1, _rl_output_character_function);
Jari Aaltobb706242000-03-17 21:46:59 +00002652#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002653 _rl_last_c_pos = 0;
Jari Aaltobb706242000-03-17 21:46:59 +00002654#if defined (__MSDOS__)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002655 space_to_eol (_rl_screenwidth);
Jari Aaltobb706242000-03-17 21:46:59 +00002656 putc ('\r', rl_outstream);
2657#else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002658 if (_rl_term_clreol)
2659 tputs (_rl_term_clreol, 1, _rl_output_character_function);
Jari Aalto726f6381996-08-26 18:22:31 +00002660 else
2661 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00002662 space_to_eol (_rl_screenwidth);
2663 tputs (_rl_term_cr, 1, _rl_output_character_function);
Jari Aalto726f6381996-08-26 18:22:31 +00002664 }
Jari Aaltobb706242000-03-17 21:46:59 +00002665#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002666 if (_rl_last_v_pos > 0)
2667 _rl_move_vert (0);
2668 }
2669 else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002670 rl_crlf ();
Jari Aalto726f6381996-08-26 18:22:31 +00002671
2672 /* Redraw only the last line of a multi-line prompt. */
2673 t = strrchr (rl_display_prompt, '\n');
2674 if (t)
Jari Aaltobb706242000-03-17 21:46:59 +00002675 redraw_prompt (++t);
Jari Aalto726f6381996-08-26 18:22:31 +00002676 else
2677 rl_forced_update_display ();
2678}
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002679
2680void
2681_rl_clean_up_for_exit ()
2682{
Jari Aalto31859422009-01-12 13:36:28 +00002683 if (_rl_echoing_p)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002684 {
Chet Rameyb7ec1812014-04-11 11:05:31 -04002685 if (_rl_vis_botlin > 0) /* minor optimization plus bug fix */
2686 _rl_move_vert (_rl_vis_botlin);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002687 _rl_vis_botlin = 0;
2688 fflush (rl_outstream);
Jari Aaltob72432f1999-02-19 17:11:39 +00002689 rl_restart_output (1, 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002690 }
2691}
Jari Aaltob72432f1999-02-19 17:11:39 +00002692
2693void
2694_rl_erase_entire_line ()
2695{
2696 cr ();
2697 _rl_clear_to_eol (0);
2698 cr ();
2699 fflush (rl_outstream);
2700}
Jari Aaltobb706242000-03-17 21:46:59 +00002701
2702/* return the `current display line' of the cursor -- the number of lines to
2703 move up to get to the first screen line of the current readline line. */
2704int
2705_rl_current_display_line ()
2706{
2707 int ret, nleft;
2708
2709 /* Find out whether or not there might be invisible characters in the
2710 editing buffer. */
2711 if (rl_display_prompt == rl_prompt)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002712 nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
Jari Aaltobb706242000-03-17 21:46:59 +00002713 else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002714 nleft = _rl_last_c_pos - _rl_screenwidth;
Jari Aaltobb706242000-03-17 21:46:59 +00002715
2716 if (nleft > 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002717 ret = 1 + nleft / _rl_screenwidth;
Jari Aaltobb706242000-03-17 21:46:59 +00002718 else
2719 ret = 0;
2720
2721 return ret;
2722}
Jari Aalto7117c2d2002-07-17 14:10:11 +00002723
2724#if defined (HANDLE_MULTIBYTE)
2725/* Calculate the number of screen columns occupied by STR from START to END.
2726 In the case of multibyte characters with stateful encoding, we have to
2727 scan from the beginning of the string to take the state into account. */
2728static int
Chet Ramey00018032011-11-21 20:51:19 -05002729_rl_col_width (str, start, end, flags)
Jari Aaltob80f6442004-07-27 13:29:18 +00002730 const char *str;
Chet Ramey00018032011-11-21 20:51:19 -05002731 int start, end, flags;
Jari Aalto7117c2d2002-07-17 14:10:11 +00002732{
2733 wchar_t wc;
Jari Aalto06285672006-10-10 14:15:34 +00002734 mbstate_t ps;
Jari Aalto7117c2d2002-07-17 14:10:11 +00002735 int tmp, point, width, max;
2736
2737 if (end <= start)
2738 return 0;
Jari Aaltof1be6662008-11-18 13:15:12 +00002739 if (MB_CUR_MAX == 1 || rl_byte_oriented)
Chet Rameyac50fba2014-02-26 09:36:43 -05002740 /* this can happen in some cases where it's inconvenient to check */
Jari Aaltof1be6662008-11-18 13:15:12 +00002741 return (end - start);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002742
Jari Aalto06285672006-10-10 14:15:34 +00002743 memset (&ps, 0, sizeof (mbstate_t));
2744
Jari Aalto7117c2d2002-07-17 14:10:11 +00002745 point = 0;
2746 max = end;
2747
Chet Ramey00018032011-11-21 20:51:19 -05002748 /* Try to short-circuit common cases. The adjustment to remove wrap_offset
2749 is done by the caller. */
2750 /* 1. prompt string */
2751 if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
2752 return (prompt_physical_chars + wrap_offset);
2753 /* 2. prompt string + line contents */
2754 else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
2755 {
2756 tmp = prompt_physical_chars + wrap_offset;
2757 /* XXX - try to call ourselves recursively with non-prompt portion */
2758 tmp += _rl_col_width (str, local_prompt_len, end, flags);
2759 return (tmp);
2760 }
2761
Jari Aalto7117c2d2002-07-17 14:10:11 +00002762 while (point < start)
2763 {
2764 tmp = mbrlen (str + point, max, &ps);
Jari Aaltob80f6442004-07-27 13:29:18 +00002765 if (MB_INVALIDCH ((size_t)tmp))
Jari Aalto7117c2d2002-07-17 14:10:11 +00002766 {
2767 /* In this case, the bytes are invalid or too short to compose a
2768 multibyte character, so we assume that the first byte represents
2769 a single character. */
2770 point++;
2771 max--;
2772
2773 /* Clear the state of the byte sequence, because in this case the
2774 effect of mbstate is undefined. */
2775 memset (&ps, 0, sizeof (mbstate_t));
2776 }
Jari Aaltob80f6442004-07-27 13:29:18 +00002777 else if (MB_NULLWCH (tmp))
2778 break; /* Found '\0' */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002779 else
2780 {
2781 point += tmp;
2782 max -= tmp;
2783 }
2784 }
2785
2786 /* If START is not a byte that starts a character, then POINT will be
2787 greater than START. In this case, assume that (POINT - START) gives
2788 a byte count that is the number of columns of difference. */
2789 width = point - start;
2790
2791 while (point < end)
2792 {
2793 tmp = mbrtowc (&wc, str + point, max, &ps);
Jari Aaltob80f6442004-07-27 13:29:18 +00002794 if (MB_INVALIDCH ((size_t)tmp))
Jari Aalto7117c2d2002-07-17 14:10:11 +00002795 {
2796 /* In this case, the bytes are invalid or too short to compose a
2797 multibyte character, so we assume that the first byte represents
2798 a single character. */
2799 point++;
2800 max--;
2801
2802 /* and assume that the byte occupies a single column. */
2803 width++;
2804
2805 /* Clear the state of the byte sequence, because in this case the
2806 effect of mbstate is undefined. */
2807 memset (&ps, 0, sizeof (mbstate_t));
2808 }
Jari Aaltob80f6442004-07-27 13:29:18 +00002809 else if (MB_NULLWCH (tmp))
2810 break; /* Found '\0' */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002811 else
2812 {
2813 point += tmp;
2814 max -= tmp;
Chet Rameyac50fba2014-02-26 09:36:43 -05002815 tmp = WCWIDTH(wc);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002816 width += (tmp >= 0) ? tmp : 1;
2817 }
2818 }
2819
2820 width += point - end;
2821
2822 return width;
2823}
2824#endif /* HANDLE_MULTIBYTE */