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