version 1.1.1.2, 2016/11/03 13:35:37
|
version 1.1.1.3, 2021/03/17 01:01:01
|
Line 1
|
Line 1
|
/* display.c -- readline redisplay facility. */ |
/* display.c -- readline redisplay facility. */ |
|
|
/* Copyright (C) 1987-2013 Free Software Foundation, Inc. | /* Copyright (C) 1987-2020 Free Software Foundation, Inc. |
|
|
This file is part of the GNU Readline Library (Readline), a library |
This file is part of the GNU Readline Library (Readline), a library |
for reading lines of text with interactive input and history editing. |
for reading lines of text with interactive input and history editing. |
Line 63
|
Line 63
|
extern char *strchr (), *strrchr (); |
extern char *strchr (), *strrchr (); |
#endif /* !strchr && !__STDC__ */ |
#endif /* !strchr && !__STDC__ */ |
|
|
static void update_line PARAMS((char *, char *, int, int, int, int)); | static void putc_face PARAMS((int, int, char *)); |
| static void puts_face PARAMS((const char *, const char *, int)); |
| static void norm_face PARAMS((char *, int)); |
| |
| static void update_line PARAMS((char *, char *, char *, char *, int, int, int, int)); |
static void space_to_eol PARAMS((int)); |
static void space_to_eol PARAMS((int)); |
static void delete_chars PARAMS((int)); |
static void delete_chars PARAMS((int)); |
static void insert_some_chars PARAMS((char *, int, int)); |
static void insert_some_chars PARAMS((char *, int, int)); |
static void open_some_spaces PARAMS((int)); |
static void open_some_spaces PARAMS((int)); |
static void cr PARAMS((void)); |
static void cr PARAMS((void)); |
|
static void redraw_prompt PARAMS((char *)); |
|
static void _rl_move_cursor_relative PARAMS((int, const char *, const char *)); |
|
|
|
/* Values for FLAGS */ |
|
#define PMT_MULTILINE 0x01 |
|
|
|
static char *expand_prompt PARAMS((char *, int, int *, int *, int *, int *)); |
|
|
|
#define DEFAULT_LINE_BUFFER_SIZE 1024 |
|
|
/* State of visible and invisible lines. */ |
/* State of visible and invisible lines. */ |
struct line_state |
struct line_state |
{ |
{ |
char *line; |
char *line; |
|
char *lface; |
int *lbreaks; |
int *lbreaks; |
int lbsize; |
int lbsize; |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
int *wrapped_line; |
|
int wbsize; |
int wbsize; |
|
int *wrapped_line; |
#endif |
#endif |
}; |
}; |
|
|
Line 96 static int line_structures_initialized = 0;
|
Line 110 static int line_structures_initialized = 0;
|
#define vis_lbsize (line_state_visible->lbsize) |
#define vis_lbsize (line_state_visible->lbsize) |
|
|
#define visible_line (line_state_visible->line) |
#define visible_line (line_state_visible->line) |
|
#define vis_face (line_state_visible->lface) |
#define invisible_line (line_state_invisible->line) |
#define invisible_line (line_state_invisible->line) |
|
#define inv_face (line_state_invisible->lface) |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
static int _rl_col_width PARAMS((const char *, int, int, int)); |
static int _rl_col_width PARAMS((const char *, int, int, int)); |
Line 113 static int _rl_col_width PARAMS((const char *, int, in
|
Line 129 static int _rl_col_width PARAMS((const char *, int, in
|
buffer index in others. This macro is used when deciding whether the |
buffer index in others. This macro is used when deciding whether the |
current cursor position is in the middle of a prompt string containing |
current cursor position is in the middle of a prompt string containing |
invisible characters. XXX - might need to take `modmark' into account. */ |
invisible characters. XXX - might need to take `modmark' into account. */ |
|
/* XXX - only valid when tested against _rl_last_c_pos; buffer indices need |
|
to use prompt_last_invisible directly. */ |
#define PROMPT_ENDING_INDEX \ |
#define PROMPT_ENDING_INDEX \ |
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) |
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) |
|
|
|
|
|
#define FACE_NORMAL '0' |
|
#define FACE_STANDOUT '1' |
|
#define FACE_INVALID ((char)1) |
|
|
/* **************************************************************** */ |
/* **************************************************************** */ |
/* */ |
/* */ |
/* Display stuff */ |
/* Display stuff */ |
Line 151 rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
|
Line 172 rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
|
/* What YOU turn on when you have handled all redisplay yourself. */ |
/* What YOU turn on when you have handled all redisplay yourself. */ |
int rl_display_fixed = 0; |
int rl_display_fixed = 0; |
|
|
int _rl_suppress_redisplay = 0; |
|
int _rl_want_redisplay = 0; |
|
|
|
/* The stuff that gets printed out before the actual text of the line. |
/* The stuff that gets printed out before the actual text of the line. |
This is usually pointing to rl_prompt. */ |
This is usually pointing to rl_prompt. */ |
char *rl_display_prompt = (char *)NULL; |
char *rl_display_prompt = (char *)NULL; |
|
|
|
/* Variables used to include the editing mode in the prompt. */ |
|
char *_rl_emacs_mode_str; |
|
int _rl_emacs_modestr_len; |
|
|
|
char *_rl_vi_ins_mode_str; |
|
int _rl_vi_ins_modestr_len; |
|
|
|
char *_rl_vi_cmd_mode_str; |
|
int _rl_vi_cmd_modestr_len; |
|
|
/* Pseudo-global variables declared here. */ |
/* Pseudo-global variables declared here. */ |
|
|
|
/* Hints for other parts of readline to give to the display engine. */ |
|
int _rl_suppress_redisplay = 0; |
|
int _rl_want_redisplay = 0; |
|
|
/* The visible cursor position. If you print some text, adjust this. */ |
/* The visible cursor position. If you print some text, adjust this. */ |
/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale |
/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale |
supporting multibyte characters, and an absolute cursor position when |
supporting multibyte characters, and an absolute cursor position when |
Line 168 char *rl_display_prompt = (char *)NULL;
|
Line 200 char *rl_display_prompt = (char *)NULL;
|
int _rl_last_c_pos = 0; |
int _rl_last_c_pos = 0; |
int _rl_last_v_pos = 0; |
int _rl_last_v_pos = 0; |
|
|
|
/* Number of physical lines consumed by the current line buffer currently |
|
on screen minus 1. */ |
|
int _rl_vis_botlin = 0; |
|
|
|
static int _rl_quick_redisplay = 0; |
|
|
|
/* This is a hint update_line gives to rl_redisplay that it has adjusted the |
|
value of _rl_last_c_pos *and* taken the presence of any invisible chars in |
|
the prompt into account. rl_redisplay notes this and does not do the |
|
adjustment itself. */ |
static int cpos_adjusted; |
static int cpos_adjusted; |
|
|
|
/* The index into the line buffer corresponding to the cursor position */ |
static int cpos_buffer_position; |
static int cpos_buffer_position; |
|
|
|
/* A flag to note when we're displaying the first line of the prompt */ |
static int displaying_prompt_first_line; |
static int displaying_prompt_first_line; |
|
/* The number of multibyte characters in the prompt, if any */ |
static int prompt_multibyte_chars; |
static int prompt_multibyte_chars; |
|
|
/* Number of lines currently on screen minus 1. */ | static int _rl_inv_botlin = 0; |
int _rl_vis_botlin = 0; | |
|
|
/* Variables used only in this file. */ |
/* Variables used only in this file. */ |
/* The last left edge of text that was displayed. This is used when |
/* The last left edge of text that was displayed. This is used when |
Line 189 static int msg_bufsiz = 0;
|
Line 235 static int msg_bufsiz = 0;
|
static int forced_display; |
static int forced_display; |
|
|
/* Default and initial buffer size. Can grow. */ |
/* Default and initial buffer size. Can grow. */ |
static int line_size = 1024; | static int line_size = 0; |
|
|
|
/* Set to a non-zero value if horizontal scrolling has been enabled |
|
automatically because the terminal was resized to height 1. */ |
|
static int horizontal_scrolling_autoset = 0; /* explicit initialization */ |
|
|
/* Variables to keep track of the expanded prompt string, which may |
/* Variables to keep track of the expanded prompt string, which may |
include invisible characters. */ |
include invisible characters. */ |
|
|
static char *local_prompt, *local_prompt_prefix; |
static char *local_prompt, *local_prompt_prefix; |
static int local_prompt_len; |
static int local_prompt_len; |
static int prompt_visible_length, prompt_prefix_length; | static int prompt_prefix_length; |
| /* Number of chars in the buffer that contribute to visible chars on the screen. |
| This might be different from the number of physical chars in the presence |
| of multibyte characters */ |
| static int prompt_visible_length; |
|
|
/* The number of invisible characters in the line currently being |
/* The number of invisible characters in the line currently being |
displayed on the screen. */ |
displayed on the screen. */ |
Line 222 static int prompt_last_screen_line;
|
Line 276 static int prompt_last_screen_line;
|
|
|
static int prompt_physical_chars; |
static int prompt_physical_chars; |
|
|
|
/* An array of indexes into the prompt string where we will break physical |
|
screen lines. It's easier to compute in expand_prompt and use later in |
|
rl_redisplay instead of having rl_redisplay try to guess about invisible |
|
characters in the prompt or use heuristics about where they are. */ |
|
static int *local_prompt_newlines; |
|
|
/* set to a non-zero value by rl_redisplay if we are marking modified history |
/* set to a non-zero value by rl_redisplay if we are marking modified history |
lines and the current line is so marked. */ |
lines and the current line is so marked. */ |
static int modmark; |
static int modmark; |
|
|
|
static int line_totbytes; |
|
|
/* Variables to save and restore prompt and display information. */ |
/* Variables to save and restore prompt and display information. */ |
|
|
/* These are getting numerous enough that it's time to create a struct. */ |
/* These are getting numerous enough that it's time to create a struct. */ |
|
|
static char *saved_local_prompt; |
static char *saved_local_prompt; |
static char *saved_local_prefix; |
static char *saved_local_prefix; |
|
static int *saved_local_prompt_newlines; |
|
|
static int saved_last_invisible; |
static int saved_last_invisible; |
static int saved_visible_length; |
static int saved_visible_length; |
static int saved_prefix_length; |
static int saved_prefix_length; |
Line 239 static int saved_local_length;
|
Line 303 static int saved_local_length;
|
static int saved_invis_chars_first_line; |
static int saved_invis_chars_first_line; |
static int saved_physical_chars; |
static int saved_physical_chars; |
|
|
/* Return a character indicating the editing mode, for use in the prompt. */ | /* Return a string indicating the editing mode, for use in the prompt. */ |
static int | |
prompt_modechar () | static char * |
| prompt_modestr (int *lenp) |
{ |
{ |
if (rl_editing_mode == emacs_mode) |
if (rl_editing_mode == emacs_mode) |
return '@'; | { |
| if (lenp) |
| *lenp = _rl_emacs_mode_str ? _rl_emacs_modestr_len : RL_EMACS_MODESTR_DEFLEN; |
| return _rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT; |
| } |
else if (_rl_keymap == vi_insertion_keymap) |
else if (_rl_keymap == vi_insertion_keymap) |
return '+'; /* vi insert mode */ | { |
| if (lenp) |
| *lenp = _rl_vi_ins_mode_str ? _rl_vi_ins_modestr_len : RL_VI_INS_MODESTR_DEFLEN; |
| return _rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT; /* vi insert mode */ |
| } |
else |
else |
return ':'; /* vi command mode */ | { |
| if (lenp) |
| *lenp = _rl_vi_cmd_mode_str ? _rl_vi_cmd_modestr_len : RL_VI_CMD_MODESTR_DEFLEN; |
| return _rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT; /* vi command mode */ |
| } |
} |
} |
|
|
/* Expand the prompt string S and return the number of visible |
/* Expand the prompt string S and return the number of visible |
Line 257 prompt_modechar ()
|
Line 334 prompt_modechar ()
|
index of the last invisible character in the returned string. NIFLP, |
index of the last invisible character in the returned string. NIFLP, |
if non-zero, is a place to store the number of invisible characters in |
if non-zero, is a place to store the number of invisible characters in |
the first prompt line. The previous are used as byte counts -- indexes |
the first prompt line. The previous are used as byte counts -- indexes |
into a character buffer. */ | into a character buffer. *VLP gets the number of physical characters in |
| the expanded prompt (visible length) */ |
|
|
/* Current implementation: |
/* Current implementation: |
\001 (^A) start non-visible characters |
\001 (^A) start non-visible characters |
Line 266 prompt_modechar ()
|
Line 344 prompt_modechar ()
|
the returned string; all characters except those between \001 and |
the returned string; all characters except those between \001 and |
\002 are assumed to be `visible'. */ |
\002 are assumed to be `visible'. */ |
|
|
|
/* Possible values for FLAGS: |
|
PMT_MULTILINE caller indicates that this is part of a multiline prompt |
|
*/ |
|
|
|
/* This approximates the number of lines the prompt will take when displayed */ |
|
#define APPROX_DIV(n, d) (((n) < (d)) ? 1 : ((n) / (d)) + 1) |
|
|
static char * |
static char * |
expand_prompt (pmt, lp, lip, niflp, vlp) | expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) |
char *pmt; | |
int *lp, *lip, *niflp, *vlp; | |
{ |
{ |
char *r, *ret, *p, *igstart; | char *r, *ret, *p, *igstart, *nprompt, *ms; |
int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; |
int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; |
|
int mlen, newlines, newlines_guess, bound; |
|
int mb_cur_max; |
|
|
/* Short-circuit if we can. */ | /* We only expand the mode string for the last line of a multiline prompt |
if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0) | (a prompt with embedded newlines). */ |
| ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0; |
| if (ms) |
{ |
{ |
if (pmt == rl_prompt && _rl_show_mode_in_prompt) | l = strlen (pmt); |
{ | nprompt = (char *)xmalloc (l + mlen + 1); |
l = strlen (pmt); | memcpy (nprompt, ms, mlen); |
r = (char *)xmalloc (l + 2); | strcpy (nprompt + mlen, pmt); |
r[0] = prompt_modechar (); | |
strcpy (r + 1, pmt); | |
} | |
else | |
r = savestring (pmt); | |
| |
if (lp) | |
*lp = strlen (r); | |
if (lip) | |
*lip = 0; | |
if (niflp) | |
*niflp = 0; | |
if (vlp) | |
*vlp = lp ? *lp : strlen (r); | |
return r; | |
} |
} |
|
else |
|
nprompt = pmt; |
|
|
l = strlen (pmt); | mb_cur_max = MB_CUR_MAX; |
r = ret = (char *)xmalloc (l + 2); | |
|
|
rl = physchars = 0; /* move up here so mode show can set them */ | if (_rl_screenwidth == 0) |
if (pmt == rl_prompt && _rl_show_mode_in_prompt) | _rl_get_screen_size (0, 0); /* avoid division by zero */ |
| |
| /* Short-circuit if we can. We can do this if we are treating the prompt as |
| a sequence of bytes and there are no invisible characters in the prompt |
| to deal with. Since we populate local_prompt_newlines, we have to run |
| through the rest of the function if this prompt looks like it's going to |
| be longer than one screen line. */ |
| if ((mb_cur_max <= 1 || rl_byte_oriented) && strchr (nprompt, RL_PROMPT_START_IGNORE) == 0) |
{ |
{ |
*r++ = prompt_modechar (); | l = strlen (nprompt); |
rl = physchars = 1; | if (l < (_rl_screenwidth > 0 ? _rl_screenwidth : 80)) |
| { |
| r = (nprompt == pmt) ? savestring (pmt) : nprompt; |
| if (lp) |
| *lp = l; |
| if (lip) |
| *lip = 0; |
| if (niflp) |
| *niflp = 0; |
| if (vlp) |
| *vlp = l; |
| |
| local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * 2); |
| local_prompt_newlines[0] = 0; |
| local_prompt_newlines[1] = -1; |
| |
| return r; |
| } |
} |
} |
|
|
invfl = 0; /* invisible chars in first line of prompt */ | l = strlen (nprompt); /* XXX */ |
invflset = 0; /* we only want to set invfl once */ | r = ret = (char *)xmalloc (l + 1); |
|
|
igstart = 0; | /* Guess at how many screen lines the prompt will take to size the array that |
for (ignoring = last = ninvis = 0, p = pmt; p && *p; p++) | keeps track of where the line wraps happen */ |
| newlines_guess = (_rl_screenwidth > 0) ? APPROX_DIV(l, _rl_screenwidth) : APPROX_DIV(l, 80); |
| local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * (newlines_guess + 1)); |
| local_prompt_newlines[newlines = 0] = 0; |
| for (rl = 1; rl <= newlines_guess; rl++) |
| local_prompt_newlines[rl] = -1; |
| |
| rl = physchars = 0; /* mode string now part of nprompt */ |
| invfl = 0; /* invisible chars in first line of prompt */ |
| invflset = 0; /* we only want to set invfl once */ |
| igstart = 0; /* we're not ignoring any characters yet */ |
| |
| for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++) |
{ |
{ |
/* This code strips the invisible character string markers |
/* This code strips the invisible character string markers |
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ |
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ |
Line 332 expand_prompt (pmt, lp, lip, niflp, vlp)
|
Line 441 expand_prompt (pmt, lp, lip, niflp, vlp)
|
else |
else |
{ |
{ |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
pind = p - pmt; | pind = p - nprompt; |
ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO); | ind = _rl_find_next_mbchar (nprompt, pind, 1, MB_FIND_NONZERO); |
l = ind - pind; |
l = ind - pind; |
while (l--) |
while (l--) |
*r++ = *p++; |
*r++ = *p++; |
Line 347 expand_prompt (pmt, lp, lip, niflp, vlp)
|
Line 456 expand_prompt (pmt, lp, lip, niflp, vlp)
|
not be the same as the number of physical characters |
not be the same as the number of physical characters |
on the screen in the presence of multibyte characters */ |
on the screen in the presence of multibyte characters */ |
rl += ind - pind; |
rl += ind - pind; |
physchars += _rl_col_width (pmt, pind, ind, 0); | physchars += _rl_col_width (nprompt, pind, ind, 0); |
} |
} |
else |
else |
ninvis += ind - pind; |
ninvis += ind - pind; |
Line 366 expand_prompt (pmt, lp, lip, niflp, vlp)
|
Line 475 expand_prompt (pmt, lp, lip, niflp, vlp)
|
ninvis++; /* invisible chars byte counter */ |
ninvis++; /* invisible chars byte counter */ |
} |
} |
|
|
if (invflset == 0 && rl >= _rl_screenwidth) | if (invflset == 0 && physchars >= _rl_screenwidth) |
{ |
{ |
invfl = ninvis; |
invfl = ninvis; |
invflset = 1; |
invflset = 1; |
} |
} |
|
|
|
if (physchars >= (bound = (newlines + 1) * _rl_screenwidth) && local_prompt_newlines[newlines+1] == -1) |
|
{ |
|
int new; |
|
if (physchars > bound) /* should rarely happen */ |
|
{ |
|
#if defined (HANDLE_MULTIBYTE) |
|
*r = '\0'; /* need null-termination for strlen */ |
|
if (mb_cur_max > 1 && rl_byte_oriented == 0) |
|
new = _rl_find_prev_mbchar (ret, r - ret, MB_FIND_ANY); |
|
else |
|
#endif |
|
new = r - ret - (physchars - bound); /* XXX */ |
|
} |
|
else |
|
new = r - ret; |
|
local_prompt_newlines[++newlines] = new; |
|
} |
} |
} |
} |
} |
|
|
Line 386 expand_prompt (pmt, lp, lip, niflp, vlp)
|
Line 513 expand_prompt (pmt, lp, lip, niflp, vlp)
|
*niflp = invfl; |
*niflp = invfl; |
if (vlp) |
if (vlp) |
*vlp = physchars; |
*vlp = physchars; |
|
|
|
if (nprompt != pmt) |
|
free (nprompt); |
|
|
return ret; |
return ret; |
} |
} |
|
|
/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from |
/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from |
PMT and return the rest of PMT. */ |
PMT and return the rest of PMT. */ |
char * |
char * |
_rl_strip_prompt (pmt) | _rl_strip_prompt (char *pmt) |
char *pmt; | |
{ |
{ |
char *ret; |
char *ret; |
|
|
ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL); | ret = expand_prompt (pmt, 0, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL); |
return ret; |
return ret; |
} |
} |
|
|
void |
void |
_rl_reset_prompt () | _rl_reset_prompt (void) |
{ |
{ |
rl_visible_prompt_length = rl_expand_prompt (rl_prompt); |
rl_visible_prompt_length = rl_expand_prompt (rl_prompt); |
} |
} |
Line 418 _rl_reset_prompt ()
|
Line 548 _rl_reset_prompt ()
|
* prompt_visible_length = number of visible characters in local_prompt |
* prompt_visible_length = number of visible characters in local_prompt |
* prompt_prefix_length = number of visible characters in local_prompt_prefix |
* prompt_prefix_length = number of visible characters in local_prompt_prefix |
* |
* |
|
* It also tries to keep track of the number of invisible characters in the |
|
* prompt string, and where they are. |
|
* |
* This function is called once per call to readline(). It may also be |
* This function is called once per call to readline(). It may also be |
* called arbitrarily to expand the primary prompt. |
* called arbitrarily to expand the primary prompt. |
* |
* |
* The return value is the number of visible characters on the last line |
* The return value is the number of visible characters on the last line |
* of the (possibly multi-line) prompt. | * of the (possibly multi-line) prompt. In this case, multi-line means |
| * there are embedded newlines in the prompt string itself, not that the |
| * number of physical characters exceeds the screen width and the prompt |
| * wraps. |
*/ |
*/ |
int |
int |
rl_expand_prompt (prompt) | rl_expand_prompt (char *prompt) |
char *prompt; | |
{ |
{ |
char *p, *t; |
char *p, *t; |
int c; |
int c; |
Line 444 rl_expand_prompt (prompt)
|
Line 579 rl_expand_prompt (prompt)
|
return (0); |
return (0); |
|
|
p = strrchr (prompt, '\n'); |
p = strrchr (prompt, '\n'); |
if (!p) | if (p == 0) |
{ |
{ |
/* The prompt is only one logical line, though it might wrap. */ |
/* The prompt is only one logical line, though it might wrap. */ |
local_prompt = expand_prompt (prompt, &prompt_visible_length, | local_prompt = expand_prompt (prompt, 0, &prompt_visible_length, |
&prompt_last_invisible, | &prompt_last_invisible, |
&prompt_invis_chars_first_line, | &prompt_invis_chars_first_line, |
&prompt_physical_chars); | &prompt_physical_chars); |
local_prompt_prefix = (char *)0; |
local_prompt_prefix = (char *)0; |
local_prompt_len = local_prompt ? strlen (local_prompt) : 0; |
local_prompt_len = local_prompt ? strlen (local_prompt) : 0; |
return (prompt_visible_length); |
return (prompt_visible_length); |
Line 459 rl_expand_prompt (prompt)
|
Line 594 rl_expand_prompt (prompt)
|
{ |
{ |
/* The prompt spans multiple lines. */ |
/* The prompt spans multiple lines. */ |
t = ++p; |
t = ++p; |
local_prompt = expand_prompt (p, &prompt_visible_length, |
|
&prompt_last_invisible, |
|
&prompt_invis_chars_first_line, |
|
&prompt_physical_chars); |
|
c = *t; *t = '\0'; |
c = *t; *t = '\0'; |
/* The portion of the prompt string up to and including the |
/* The portion of the prompt string up to and including the |
final newline is now null-terminated. */ |
final newline is now null-terminated. */ |
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length, | local_prompt_prefix = expand_prompt (prompt, PMT_MULTILINE, |
| &prompt_prefix_length, |
(int *)NULL, |
(int *)NULL, |
(int *)NULL, |
(int *)NULL, |
(int *)NULL); |
(int *)NULL); |
*t = c; |
*t = c; |
|
|
|
local_prompt = expand_prompt (p, PMT_MULTILINE, |
|
&prompt_visible_length, |
|
&prompt_last_invisible, |
|
&prompt_invis_chars_first_line, |
|
&prompt_physical_chars); |
local_prompt_len = local_prompt ? strlen (local_prompt) : 0; |
local_prompt_len = local_prompt ? strlen (local_prompt) : 0; |
return (prompt_prefix_length); |
return (prompt_prefix_length); |
} |
} |
} |
} |
|
|
|
/* Allocate the various line structures, making sure they can hold MINSIZE |
|
bytes. If the existing line size can accommodate MINSIZE bytes, don't do |
|
anything. */ |
|
static void |
|
realloc_line (int minsize) |
|
{ |
|
int minimum_size; |
|
int newsize, delta; |
|
|
|
minimum_size = DEFAULT_LINE_BUFFER_SIZE; |
|
if (minsize < minimum_size) |
|
minsize = minimum_size; |
|
if (minsize <= _rl_screenwidth) /* XXX - for gdb */ |
|
minsize = _rl_screenwidth + 1; |
|
if (line_size >= minsize) |
|
return; |
|
|
|
newsize = minimum_size; |
|
while (newsize < minsize) |
|
newsize *= 2; |
|
|
|
visible_line = (char *)xrealloc (visible_line, newsize); |
|
vis_face = (char *)xrealloc (vis_face, newsize); |
|
|
|
invisible_line = (char *)xrealloc (invisible_line, newsize); |
|
inv_face = (char *)xrealloc (inv_face, newsize); |
|
|
|
delta = newsize - line_size; |
|
memset (visible_line + line_size, 0, delta); |
|
memset (vis_face + line_size, FACE_NORMAL, delta); |
|
memset (invisible_line + line_size, 1, delta); |
|
memset (inv_face + line_size, FACE_INVALID, delta); |
|
|
|
line_size = newsize; |
|
} |
|
|
/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated |
/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated |
arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE |
arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE |
and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is |
and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is |
increased. If the lines have already been allocated, this ensures that |
increased. If the lines have already been allocated, this ensures that |
they can hold at least MINSIZE characters. */ |
they can hold at least MINSIZE characters. */ |
static void |
static void |
init_line_structures (minsize) | init_line_structures (int minsize) |
int minsize; | |
{ |
{ |
register int n; |
|
|
|
if (invisible_line == 0) /* initialize it */ |
if (invisible_line == 0) /* initialize it */ |
{ |
{ |
if (line_size < minsize) | if (line_size > minsize) |
line_size = minsize; | minsize = line_size; |
visible_line = (char *)xmalloc (line_size); | |
invisible_line = (char *)xmalloc (line_size); | |
} |
} |
else if (line_size < minsize) /* ensure it can hold MINSIZE chars */ | realloc_line (minsize); |
{ | |
line_size *= 2; | |
if (line_size < minsize) | |
line_size = minsize; | |
visible_line = (char *)xrealloc (visible_line, line_size); | |
invisible_line = (char *)xrealloc (invisible_line, line_size); | |
} | |
|
|
for (n = minsize; n < line_size; n++) |
|
{ |
|
visible_line[n] = 0; |
|
invisible_line[n] = 1; |
|
} |
|
|
|
if (vis_lbreaks == 0) |
if (vis_lbreaks == 0) |
{ |
{ |
/* should be enough. */ |
/* should be enough. */ |
Line 529 init_line_structures (minsize)
|
Line 685 init_line_structures (minsize)
|
|
|
line_structures_initialized = 1; |
line_structures_initialized = 1; |
} |
} |
| |
/* Basic redisplay algorithm. */ | /* Convenience functions to add chars to the invisible line that update the |
| face information at the same time. */ |
| static void /* XXX - change this */ |
| invis_addc (int *outp, char c, char face) |
| { |
| realloc_line (*outp + 1); |
| invisible_line[*outp] = c; |
| inv_face[*outp] = face; |
| *outp += 1; |
| } |
| |
| static void |
| invis_adds (int *outp, const char *str, int n, char face) |
| { |
| int i; |
| |
| for (i = 0; i < n; i++) |
| invis_addc (outp, str[i], face); |
| } |
| |
| static void |
| invis_nul (int *outp) |
| { |
| invis_addc (outp, '\0', 0); |
| *outp -= 1; |
| } |
| |
| static void |
| set_active_region (int *beg, int *end) |
| { |
| if (rl_point >= 0 && rl_point <= rl_end && rl_mark >= 0 && rl_mark <= rl_end) |
| { |
| *beg = (rl_mark < rl_point) ? rl_mark : rl_point; |
| *end = (rl_mark < rl_point) ? rl_point : rl_mark; |
| } |
| } |
| |
| /* Do whatever tests are necessary and tell update_line that it can do a |
| quick, dumb redisplay on the assumption that there are so many |
| differences between the old and new lines that it would be a waste to |
| compute all the differences. |
| Right now, it just sets _rl_quick_redisplay if the current visible line |
| is a single line (so we don't have to move vertically or mess with line |
| wrapping). */ |
void |
void |
rl_redisplay () | _rl_optimize_redisplay (void) |
{ |
{ |
register int in, out, c, linenum, cursor_linenum; | if (_rl_vis_botlin == 0) |
register char *line; | _rl_quick_redisplay = 1; |
| } |
| |
| /* Basic redisplay algorithm. See comments inline. */ |
| void |
| rl_redisplay (void) |
| { |
| int in, out, c, linenum, cursor_linenum; |
int inv_botlin, lb_botlin, lb_linenum, o_cpos; |
int inv_botlin, lb_botlin, lb_linenum, o_cpos; |
int newlines, lpos, temp, n0, num, prompt_lines_estimate; |
int newlines, lpos, temp, n0, num, prompt_lines_estimate; |
char *prompt_this_line; |
char *prompt_this_line; |
|
char cur_face; |
|
int hl_begin, hl_end; |
|
int mb_cur_max = MB_CUR_MAX; |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
wchar_t wc; |
wchar_t wc; |
size_t wc_bytes; |
size_t wc_bytes; |
Line 555 rl_redisplay ()
|
Line 764 rl_redisplay ()
|
_rl_block_sigint (); |
_rl_block_sigint (); |
RL_SETSTATE (RL_STATE_REDISPLAYING); |
RL_SETSTATE (RL_STATE_REDISPLAYING); |
|
|
|
cur_face = FACE_NORMAL; |
|
/* Can turn this into an array for multiple highlighted objects in addition |
|
to the region */ |
|
hl_begin = hl_end = -1; |
|
|
|
if (rl_mark_active_p ()) |
|
set_active_region (&hl_begin, &hl_end); |
|
|
if (!rl_display_prompt) |
if (!rl_display_prompt) |
rl_display_prompt = ""; |
rl_display_prompt = ""; |
|
|
Line 563 rl_redisplay ()
|
Line 780 rl_redisplay ()
|
init_line_structures (0); |
init_line_structures (0); |
rl_on_new_line (); |
rl_on_new_line (); |
} |
} |
|
else if (line_size <= _rl_screenwidth) |
|
init_line_structures (_rl_screenwidth + 1); |
|
|
|
/* Enable horizontal scrolling automatically for terminals of height 1 |
|
where wrapping lines doesn't work. Disable it as soon as the terminal |
|
height is increased again if it was automatically enabled. */ |
|
if (_rl_screenheight <= 1) |
|
{ |
|
if (_rl_horizontal_scroll_mode == 0) |
|
horizontal_scrolling_autoset = 1; |
|
_rl_horizontal_scroll_mode = 1; |
|
} |
|
else if (horizontal_scrolling_autoset) |
|
_rl_horizontal_scroll_mode = 0; |
|
|
/* Draw the line into the buffer. */ |
/* Draw the line into the buffer. */ |
cpos_buffer_position = -1; |
cpos_buffer_position = -1; |
|
|
prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars; |
prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars; |
|
|
line = invisible_line; |
|
out = inv_botlin = 0; |
out = inv_botlin = 0; |
|
|
/* Mark the line as modified or not. We only do this for history |
/* Mark the line as modified or not. We only do this for history |
Line 577 rl_redisplay ()
|
Line 807 rl_redisplay ()
|
modmark = 0; |
modmark = 0; |
if (_rl_mark_modified_lines && current_history () && rl_undo_list) |
if (_rl_mark_modified_lines && current_history () && rl_undo_list) |
{ |
{ |
line[out++] = '*'; | invis_addc (&out, '*', cur_face); |
line[out] = '\0'; | invis_nul (&out); |
modmark = 1; |
modmark = 1; |
} |
} |
|
|
Line 591 rl_redisplay ()
|
Line 821 rl_redisplay ()
|
/* If the prompt to be displayed is the `primary' readline prompt (the |
/* If the prompt to be displayed is the `primary' readline prompt (the |
one passed to readline()), use the values we have already expanded. |
one passed to readline()), use the values we have already expanded. |
If not, use what's already in rl_display_prompt. WRAP_OFFSET is the |
If not, use what's already in rl_display_prompt. WRAP_OFFSET is the |
number of non-visible characters in the prompt string. */ | number of non-visible characters (bytes) in the prompt string. */ |
| /* This is where we output the characters in the prompt before the last |
| newline, if any. If there aren't any embedded newlines, we don't |
| write anything. Copy the last line of the prompt string into the line in |
| any case */ |
if (rl_display_prompt == rl_prompt || local_prompt) |
if (rl_display_prompt == rl_prompt || local_prompt) |
{ |
{ |
if (local_prompt_prefix && forced_display) |
if (local_prompt_prefix && forced_display) |
_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); |
_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); |
|
|
if (local_prompt_len > 0) |
if (local_prompt_len > 0) |
{ | invis_adds (&out, local_prompt, local_prompt_len, cur_face); |
temp = local_prompt_len + out + 2; | invis_nul (&out); |
if (temp >= line_size) | |
{ | |
line_size = (temp + 1024) - (temp % 1024); | |
visible_line = (char *)xrealloc (visible_line, line_size); | |
line = invisible_line = (char *)xrealloc (invisible_line, line_size); | |
} | |
strncpy (line + out, local_prompt, local_prompt_len); | |
out += local_prompt_len; | |
} | |
line[out] = '\0'; | |
wrap_offset = local_prompt_len - prompt_visible_length; |
wrap_offset = local_prompt_len - prompt_visible_length; |
} |
} |
else |
else |
Line 632 rl_redisplay ()
|
Line 856 rl_redisplay ()
|
} |
} |
} |
} |
|
|
prompt_physical_chars = pmtlen = strlen (prompt_this_line); | prompt_physical_chars = pmtlen = strlen (prompt_this_line); /* XXX */ |
temp = pmtlen + out + 2; | invis_adds (&out, prompt_this_line, pmtlen, cur_face); |
if (temp >= line_size) | invis_nul (&out); |
{ | |
line_size = (temp + 1024) - (temp % 1024); | |
visible_line = (char *)xrealloc (visible_line, line_size); | |
line = invisible_line = (char *)xrealloc (invisible_line, line_size); | |
} | |
strncpy (line + out, prompt_this_line, pmtlen); | |
out += pmtlen; | |
line[out] = '\0'; | |
wrap_offset = prompt_invis_chars_first_line = 0; |
wrap_offset = prompt_invis_chars_first_line = 0; |
} |
} |
|
|
|
#if defined (HANDLE_MULTIBYTE) |
#define CHECK_INV_LBREAKS() \ |
#define CHECK_INV_LBREAKS() \ |
do { \ |
do { \ |
if (newlines >= (inv_lbsize - 2)) \ |
if (newlines >= (inv_lbsize - 2)) \ |
Line 653 rl_redisplay ()
|
Line 870 rl_redisplay ()
|
inv_lbsize *= 2; \ |
inv_lbsize *= 2; \ |
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ |
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ |
} \ |
} \ |
|
if (newlines >= (line_state_invisible->wbsize - 2)) \ |
|
{ \ |
|
line_state_invisible->wbsize *= 2; \ |
|
line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \ |
|
} \ |
} while (0) |
} while (0) |
|
#else |
|
#define CHECK_INV_LBREAKS() \ |
|
do { \ |
|
if (newlines >= (inv_lbsize - 2)) \ |
|
{ \ |
|
inv_lbsize *= 2; \ |
|
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ |
|
} \ |
|
} while (0) |
|
#endif /* !HANDLE_MULTIBYTE */ |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
#define CHECK_LPOS() \ |
#define CHECK_LPOS() \ |
Line 667 rl_redisplay ()
|
Line 899 rl_redisplay ()
|
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ |
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ |
} \ |
} \ |
inv_lbreaks[++newlines] = out; \ |
inv_lbreaks[++newlines] = out; \ |
if (newlines >= (line_state_invisible->wbsize - 1)) \ | if (newlines >= (line_state_invisible->wbsize - 2)) \ |
{ \ |
{ \ |
line_state_invisible->wbsize *= 2; \ |
line_state_invisible->wbsize *= 2; \ |
line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \ |
line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \ |
Line 695 rl_redisplay ()
|
Line 927 rl_redisplay ()
|
|
|
/* inv_lbreaks[i] is where line i starts in the buffer. */ |
/* inv_lbreaks[i] is where line i starts in the buffer. */ |
inv_lbreaks[newlines = 0] = 0; |
inv_lbreaks[newlines = 0] = 0; |
|
/* lpos is a physical cursor position, so it needs to be adjusted by the |
|
number of invisible characters in the prompt, per line. We compute |
|
the line breaks in the prompt string in expand_prompt, taking invisible |
|
characters into account, and if lpos exceeds the screen width, we copy |
|
the data in the loop below. */ |
lpos = prompt_physical_chars + modmark; |
lpos = prompt_physical_chars + modmark; |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
Line 702 rl_redisplay ()
|
Line 939 rl_redisplay ()
|
num = 0; |
num = 0; |
#endif |
#endif |
|
|
/* prompt_invis_chars_first_line is the number of invisible characters in | /* prompt_invis_chars_first_line is the number of invisible characters (bytes) |
the first physical line of the prompt. | in the first physical line of the prompt. |
wrap_offset - prompt_invis_chars_first_line is the number of invis | wrap_offset - prompt_invis_chars_first_line is usually the number of |
chars on the second (or, more generally, last) line. */ | invis chars on the second (or, more generally, last) line. */ |
|
|
/* This is zero-based, used to set the newlines */ |
/* This is zero-based, used to set the newlines */ |
prompt_lines_estimate = lpos / _rl_screenwidth; |
prompt_lines_estimate = lpos / _rl_screenwidth; |
|
|
/* what if lpos is already >= _rl_screenwidth before we start drawing the |
/* what if lpos is already >= _rl_screenwidth before we start drawing the |
contents of the command line? */ |
contents of the command line? */ |
while (lpos >= _rl_screenwidth) | if (lpos >= _rl_screenwidth) |
{ |
{ |
int z; | temp = 0; |
/* fix from Darin Johnson <darin@acuson.com> for prompt string with | |
invisible characters that is longer than the screen width. The | /* first copy the linebreaks array we computed in expand_prompt */ |
prompt_invis_chars_first_line variable could be made into an array | while (local_prompt_newlines[newlines+1] != -1) |
saying how many invisible characters there are per line, but that's | |
probably too much work for the benefit gained. How many people have | |
prompts that exceed two physical lines? | |
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */ | |
#if defined (HANDLE_MULTIBYTE) | |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) | |
{ |
{ |
n0 = num; | temp = local_prompt_newlines[newlines+1]; |
temp = local_prompt_len; | inv_lbreaks[++newlines] = temp; |
while (num < temp) | } |
{ | |
z = _rl_col_width (local_prompt, n0, num, 1); | |
if (z > _rl_screenwidth) | |
{ | |
num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); | |
break; | |
} | |
else if (z == _rl_screenwidth) | |
break; | |
num++; | |
} | |
temp = num; | |
} | |
else | |
#endif /* !HANDLE_MULTIBYTE */ | |
temp = ((newlines + 1) * _rl_screenwidth); | |
|
|
/* Now account for invisible characters in the current line. */ | /* Now set lpos from the last newline */ |
/* XXX - this assumes that the invisible characters may be split, but only | if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) |
between the first and the last lines. */ | lpos = _rl_col_width (local_prompt, temp, local_prompt_len, 1) - (wrap_offset - prompt_invis_chars_first_line); |
temp += (newlines == 0) ? prompt_invis_chars_first_line | |
: ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line); | |
| |
inv_lbreaks[++newlines] = temp; | |
#if defined (HANDLE_MULTIBYTE) | |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) | |
lpos -= _rl_col_width (local_prompt, n0, num, 1); | |
else |
else |
#endif | lpos -= (_rl_screenwidth * newlines); |
lpos -= _rl_screenwidth; | |
} |
} |
|
|
prompt_last_screen_line = newlines; |
prompt_last_screen_line = newlines; |
|
|
/* Draw the rest of the line (after the prompt) into invisible_line, keeping |
/* Draw the rest of the line (after the prompt) into invisible_line, keeping |
track of where the cursor is (cpos_buffer_position), the number of the line containing | track of where the cursor is (cpos_buffer_position), the number of the |
the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin). | line containing the cursor (lb_linenum), the last line number (lb_botlin |
| and inv_botlin). |
It maintains an array of line breaks for display (inv_lbreaks). |
It maintains an array of line breaks for display (inv_lbreaks). |
This handles expanding tabs for display and displaying meta characters. */ |
This handles expanding tabs for display and displaying meta characters. */ |
lb_linenum = 0; |
lb_linenum = 0; |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
in = 0; |
in = 0; |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
memset (&ps, 0, sizeof (mbstate_t)); |
memset (&ps, 0, sizeof (mbstate_t)); |
/* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */ | if (_rl_utf8locale && UTF8_SINGLEBYTE(rl_line_buffer[0])) |
wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps); | { |
| wc = (wchar_t)rl_line_buffer[0]; |
| wc_bytes = 1; |
| } |
| else |
| wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps); |
} |
} |
else |
else |
wc_bytes = 1; |
wc_bytes = 1; |
Line 783 rl_redisplay ()
|
Line 996 rl_redisplay ()
|
for (in = 0; in < rl_end; in++) |
for (in = 0; in < rl_end; in++) |
#endif |
#endif |
{ |
{ |
|
if (in == hl_begin) |
|
cur_face = FACE_STANDOUT; |
|
else if (in == hl_end) |
|
cur_face = FACE_NORMAL; |
|
|
c = (unsigned char)rl_line_buffer[in]; |
c = (unsigned char)rl_line_buffer[in]; |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
if (MB_INVALIDCH (wc_bytes)) |
if (MB_INVALIDCH (wc_bytes)) |
{ |
{ |
Line 807 rl_redisplay ()
|
Line 1025 rl_redisplay ()
|
} |
} |
#endif |
#endif |
|
|
if (out + 8 >= line_size) /* XXX - 8 for \t */ |
|
{ |
|
line_size *= 2; |
|
visible_line = (char *)xrealloc (visible_line, line_size); |
|
invisible_line = (char *)xrealloc (invisible_line, line_size); |
|
line = invisible_line; |
|
} |
|
|
|
if (in == rl_point) |
if (in == rl_point) |
{ |
{ |
cpos_buffer_position = out; |
cpos_buffer_position = out; |
Line 829 rl_redisplay ()
|
Line 1039 rl_redisplay ()
|
{ |
{ |
if (_rl_output_meta_chars == 0) |
if (_rl_output_meta_chars == 0) |
{ |
{ |
sprintf (line + out, "\\%o", c); | char obuf[5]; |
| int olen; |
|
|
if (lpos + 4 >= _rl_screenwidth) | olen = sprintf (obuf, "\\%o", c); |
| |
| if (lpos + olen >= _rl_screenwidth) |
{ |
{ |
temp = _rl_screenwidth - lpos; |
temp = _rl_screenwidth - lpos; |
CHECK_INV_LBREAKS (); |
CHECK_INV_LBREAKS (); |
inv_lbreaks[++newlines] = out + temp; |
inv_lbreaks[++newlines] = out + temp; |
lpos = 4 - temp; | #if defined (HANDLE_MULTIBYTE) |
| line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; |
| #endif |
| lpos = olen - temp; |
} |
} |
else |
else |
lpos += 4; | lpos += olen; |
|
|
out += 4; | for (temp = 0; temp < olen; temp++) |
| { |
| invis_addc (&out, obuf[temp], cur_face); |
| CHECK_LPOS (); |
| } |
} |
} |
else |
else |
{ |
{ |
line[out++] = c; | invis_addc (&out, c, cur_face); |
CHECK_LPOS(); |
CHECK_LPOS(); |
} |
} |
} |
} |
Line 854 rl_redisplay ()
|
Line 1074 rl_redisplay ()
|
{ |
{ |
register int newout; |
register int newout; |
|
|
#if 0 |
|
newout = (out | (int)7) + 1; |
|
#else |
|
newout = out + 8 - lpos % 8; |
newout = out + 8 - lpos % 8; |
#endif |
|
temp = newout - out; |
temp = newout - out; |
if (lpos + temp >= _rl_screenwidth) |
if (lpos + temp >= _rl_screenwidth) |
{ |
{ |
Line 866 rl_redisplay ()
|
Line 1082 rl_redisplay ()
|
temp2 = _rl_screenwidth - lpos; |
temp2 = _rl_screenwidth - lpos; |
CHECK_INV_LBREAKS (); |
CHECK_INV_LBREAKS (); |
inv_lbreaks[++newlines] = out + temp2; |
inv_lbreaks[++newlines] = out + temp2; |
|
#if defined (HANDLE_MULTIBYTE) |
|
line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; |
|
#endif |
lpos = temp - temp2; |
lpos = temp - temp2; |
while (out < newout) |
while (out < newout) |
line[out++] = ' '; | invis_addc (&out, ' ', cur_face); |
} |
} |
else |
else |
{ |
{ |
while (out < newout) |
while (out < newout) |
line[out++] = ' '; | invis_addc (&out, ' ', cur_face); |
lpos += temp; |
lpos += temp; |
} |
} |
} |
} |
#endif |
#endif |
else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) |
else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) |
{ |
{ |
line[out++] = '\0'; /* XXX - sentinel */ | invis_addc (&out, '\0', cur_face); |
CHECK_INV_LBREAKS (); |
CHECK_INV_LBREAKS (); |
inv_lbreaks[++newlines] = out; |
inv_lbreaks[++newlines] = out; |
|
#if defined (HANDLE_MULTIBYTE) |
|
line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; |
|
#endif |
lpos = 0; |
lpos = 0; |
} |
} |
else if (CTRL_CHAR (c) || c == RUBOUT) |
else if (CTRL_CHAR (c) || c == RUBOUT) |
{ |
{ |
line[out++] = '^'; | invis_addc (&out, '^', cur_face); |
CHECK_LPOS(); |
CHECK_LPOS(); |
line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?'; | invis_addc (&out, CTRL_CHAR (c) ? UNCTRL (c) : '?', cur_face); |
CHECK_LPOS(); |
CHECK_LPOS(); |
} |
} |
else |
else |
{ |
{ |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
register int i; |
register int i; |
|
|
Line 905 rl_redisplay ()
|
Line 1127 rl_redisplay ()
|
for (i = lpos; i < _rl_screenwidth; i++) |
for (i = lpos; i < _rl_screenwidth; i++) |
{ |
{ |
/* The space will be removed in update_line() */ |
/* The space will be removed in update_line() */ |
line[out++] = ' '; | invis_addc (&out, ' ', cur_face); |
_rl_wrapped_multicolumn++; |
_rl_wrapped_multicolumn++; |
CHECK_LPOS(); |
CHECK_LPOS(); |
} |
} |
Line 915 rl_redisplay ()
|
Line 1137 rl_redisplay ()
|
lb_linenum = newlines; |
lb_linenum = newlines; |
} |
} |
for (i = in; i < in+wc_bytes; i++) |
for (i = in; i < in+wc_bytes; i++) |
line[out++] = rl_line_buffer[i]; | invis_addc (&out, rl_line_buffer[i], cur_face); |
for (i = 0; i < wc_width; i++) |
for (i = 0; i < wc_width; i++) |
CHECK_LPOS(); |
CHECK_LPOS(); |
} |
} |
else |
else |
{ |
{ |
line[out++] = c; | invis_addc (&out, c, cur_face); |
CHECK_LPOS(); |
CHECK_LPOS(); |
} |
} |
#else |
#else |
line[out++] = c; | invis_addc (&out, c, cur_face); |
CHECK_LPOS(); |
CHECK_LPOS(); |
#endif |
#endif |
} |
} |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
in += wc_bytes; |
in += wc_bytes; |
/* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */ | if (_rl_utf8locale && UTF8_SINGLEBYTE(rl_line_buffer[in])) |
wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps); | { |
| wc = (wchar_t)rl_line_buffer[in]; |
| wc_bytes = 1; |
| memset (&ps, 0, sizeof (mbstate_t)); /* re-init state */ |
| } |
| else |
| wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps); |
} |
} |
else |
else |
in++; |
in++; |
#endif |
#endif |
|
|
} |
} |
line[out] = '\0'; | invis_nul (&out); |
| line_totbytes = out; |
if (cpos_buffer_position < 0) |
if (cpos_buffer_position < 0) |
{ |
{ |
cpos_buffer_position = out; |
cpos_buffer_position = out; |
lb_linenum = newlines; |
lb_linenum = newlines; |
} |
} |
|
|
inv_botlin = lb_botlin = newlines; | /* If we are switching from one line to multiple wrapped lines, we don't |
| want to do a dumb update (or we want to make it smarter). */ |
| if (_rl_quick_redisplay && newlines > 0) |
| _rl_quick_redisplay = 0; |
| |
| inv_botlin = lb_botlin = _rl_inv_botlin = newlines; |
CHECK_INV_LBREAKS (); |
CHECK_INV_LBREAKS (); |
inv_lbreaks[newlines+1] = out; |
inv_lbreaks[newlines+1] = out; |
|
#if defined (HANDLE_MULTIBYTE) |
|
/* This should be 0 anyway */ |
|
line_state_invisible->wrapped_line[newlines+1] = _rl_wrapped_multicolumn; |
|
#endif |
cursor_linenum = lb_linenum; |
cursor_linenum = lb_linenum; |
|
|
/* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed. |
/* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed. |
Line 979 rl_redisplay ()
|
Line 1216 rl_redisplay ()
|
not the first. */ |
not the first. */ |
if (out >= _rl_screenchars) |
if (out >= _rl_screenchars) |
{ |
{ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | #if defined (HANDLE_MULTIBYTE) |
out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY); | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
| out = _rl_find_prev_mbchar (invisible_line, _rl_screenchars, MB_FIND_ANY); |
else |
else |
|
#endif |
out = _rl_screenchars - 1; |
out = _rl_screenchars - 1; |
} |
} |
|
|
Line 997 rl_redisplay ()
|
Line 1236 rl_redisplay ()
|
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) |
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) |
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) |
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) |
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line]) |
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line]) |
|
#define VIS_FACE(line) (vis_face + vis_lbreaks[line]) |
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) |
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) |
|
#define VIS_LINE_FACE(line) ((line) > _rl_vis_botlin) ? "" : VIS_FACE(line) |
#define INV_LINE(line) (invisible_line + inv_lbreaks[line]) |
#define INV_LINE(line) (invisible_line + inv_lbreaks[line]) |
|
#define INV_LINE_FACE(line) (inv_face + inv_lbreaks[line]) |
|
|
#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \ |
#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \ |
_rl_last_c_pos != o_cpos && \ |
_rl_last_c_pos != o_cpos && \ |
_rl_last_c_pos > wrap_offset && \ |
_rl_last_c_pos > wrap_offset && \ |
o_cpos < prompt_last_invisible) |
o_cpos < prompt_last_invisible) |
|
|
|
|
|
/* We don't want to highlight anything that's going to be off the top |
|
of the display; if the current line takes up more than an entire |
|
screen, just mark the lines that won't be displayed as having a |
|
`normal' face. |
|
It's imperfect, but better than display corruption. */ |
|
if (rl_mark_active_p () && inv_botlin > _rl_screenheight) |
|
{ |
|
int extra; |
|
|
|
extra = inv_botlin - _rl_screenheight; |
|
for (linenum = 0; linenum <= extra; linenum++) |
|
norm_face (INV_LINE_FACE(linenum), INV_LLEN (linenum)); |
|
} |
|
|
/* For each line in the buffer, do the updating display. */ |
/* For each line in the buffer, do the updating display. */ |
for (linenum = 0; linenum <= inv_botlin; linenum++) |
for (linenum = 0; linenum <= inv_botlin; linenum++) |
{ |
{ |
Line 1012 rl_redisplay ()
|
Line 1269 rl_redisplay ()
|
the locale from a non-multibyte to a multibyte one. */ |
the locale from a non-multibyte to a multibyte one. */ |
o_cpos = _rl_last_c_pos; |
o_cpos = _rl_last_c_pos; |
cpos_adjusted = 0; |
cpos_adjusted = 0; |
update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, | update_line (VIS_LINE(linenum), VIS_LINE_FACE(linenum), |
| INV_LINE(linenum), INV_LINE_FACE(linenum), |
| linenum, |
VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin); |
VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin); |
|
|
/* update_line potentially changes _rl_last_c_pos, but doesn't |
/* update_line potentially changes _rl_last_c_pos, but doesn't |
take invisible characters into account, since _rl_last_c_pos |
take invisible characters into account, since _rl_last_c_pos |
is an absolute cursor position in a multibyte locale. See | is an absolute cursor position in a multibyte locale. We |
if compensating here is the right thing, or if we have to | choose to (mostly) compensate for that here, rather than |
change update_line itself. There are several cases in which |
change update_line itself. There are several cases in which |
update_line adjusts _rl_last_c_pos itself (so it can pass |
update_line adjusts _rl_last_c_pos itself (so it can pass |
_rl_move_cursor_relative accurate values); it communicates |
_rl_move_cursor_relative accurate values); it communicates |
Line 1027 rl_redisplay ()
|
Line 1286 rl_redisplay ()
|
time update_line is called, then we can assume in our |
time update_line is called, then we can assume in our |
calculations that o_cpos does not need to be adjusted by |
calculations that o_cpos does not need to be adjusted by |
wrap_offset. */ |
wrap_offset. */ |
if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT()) | if (linenum == 0 && (mb_cur_max > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT()) |
_rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ |
_rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ |
else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth && | else if (cpos_adjusted == 0 && |
(MB_CUR_MAX > 1 && rl_byte_oriented == 0) && | linenum == prompt_last_screen_line && |
cpos_adjusted == 0 && | prompt_physical_chars > _rl_screenwidth && |
| (mb_cur_max > 1 && rl_byte_oriented == 0) && |
_rl_last_c_pos != o_cpos && |
_rl_last_c_pos != o_cpos && |
_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line)) | _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line)) /* XXX - rethink this last one */ |
| /* This assumes that all the invisible characters are split |
| between the first and last lines of the prompt, if the |
| prompt consumes more than two lines. It's usually right */ |
| /* XXX - not sure this is ever executed */ |
_rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line); |
_rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line); |
| |
/* If this is the line with the prompt, we might need to |
/* If this is the line with the prompt, we might need to |
compensate for invisible characters in the new line. Do |
compensate for invisible characters in the new line. Do |
this only if there is not more than one new line (which |
this only if there is not more than one new line (which |
Line 1047 rl_redisplay ()
|
Line 1311 rl_redisplay ()
|
(wrap_offset > visible_wrap_offset) && |
(wrap_offset > visible_wrap_offset) && |
(_rl_last_c_pos < visible_first_line_len)) |
(_rl_last_c_pos < visible_first_line_len)) |
{ |
{ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
nleft = _rl_screenwidth - _rl_last_c_pos; |
nleft = _rl_screenwidth - _rl_last_c_pos; |
else |
else |
nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; |
nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; |
Line 1055 rl_redisplay ()
|
Line 1319 rl_redisplay ()
|
_rl_clear_to_eol (nleft); |
_rl_clear_to_eol (nleft); |
} |
} |
#if 0 |
#if 0 |
/* This segment is intended to handle the case where the prompt | /* This segment is intended to handle the case where the old |
has invisible characters on the second line and the new line | visible prompt has invisible characters and the new line |
to be displayed needs to clear the rest of the old characters |
to be displayed needs to clear the rest of the old characters |
out (e.g., when printing the i-search prompt). In general, | out (e.g., when printing the i-search prompt): in general, |
the case of the new line being shorter than the old. | the case of the new line being shorter than the old. We need |
Incomplete */ | to be at the end of the new line and the old line needs to be |
else if (linenum == prompt_last_screen_line && | longer than the current cursor position. It's not perfect, |
prompt_physical_chars > _rl_screenwidth && | since it uses the byte length of the first line, but this will |
wrap_offset != prompt_invis_chars_first_line && | at worst result in some extra clear-to-end-of-lines. We can't |
| use the prompt length variables because they may not |
| correspond to the visible line (see printing the i-search |
| prompt above). The tests for differing numbers of invisible |
| characters may not matter and can probably be removed. */ |
| else if (linenum == 0 && |
| linenum == prompt_last_screen_line && |
_rl_last_c_pos == out && |
_rl_last_c_pos == out && |
|
_rl_last_c_pos < visible_first_line_len && |
|
visible_wrap_offset && |
|
visible_wrap_offset != wrap_offset) |
|
{ |
|
if (mb_cur_max > 1 && rl_byte_oriented == 0) |
|
nleft = _rl_screenwidth - _rl_last_c_pos; |
|
else |
|
nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; |
|
if (nleft) |
|
_rl_clear_to_eol (nleft); |
|
} |
#endif |
#endif |
|
|
|
|
/* Since the new first line is now visible, save its length. */ |
/* Since the new first line is now visible, save its length. */ |
if (linenum == 0) |
if (linenum == 0) |
visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset; |
visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset; |
Line 1082 rl_redisplay ()
|
Line 1362 rl_redisplay ()
|
{ |
{ |
tt = VIS_CHARS (linenum); |
tt = VIS_CHARS (linenum); |
_rl_move_vert (linenum); |
_rl_move_vert (linenum); |
_rl_move_cursor_relative (0, tt); | _rl_move_cursor_relative (0, tt, VIS_FACE(linenum)); |
_rl_clear_to_eol |
_rl_clear_to_eol |
((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth); |
((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth); |
} |
} |
Line 1099 rl_redisplay ()
|
Line 1379 rl_redisplay ()
|
the physical cursor position on the screen stays the same, |
the physical cursor position on the screen stays the same, |
but the buffer position needs to be adjusted to account |
but the buffer position needs to be adjusted to account |
for invisible characters. */ |
for invisible characters. */ |
if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset) | if ((mb_cur_max == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset) |
_rl_last_c_pos += wrap_offset; |
_rl_last_c_pos += wrap_offset; |
} |
} |
|
|
|
/* Now we move the cursor to where it needs to be. First, make |
|
sure we are on the correct line (cursor_linenum). */ |
|
|
/* We have to reprint the prompt if it contains invisible |
/* We have to reprint the prompt if it contains invisible |
characters, since it's not generally OK to just reprint |
characters, since it's not generally OK to just reprint |
the characters from the current cursor position. But we |
the characters from the current cursor position. But we |
only need to reprint it if the cursor is before the last |
only need to reprint it if the cursor is before the last |
invisible character in the prompt string. */ |
invisible character in the prompt string. */ |
|
/* XXX - why not use local_prompt_len? */ |
nleft = prompt_visible_length + wrap_offset; |
nleft = prompt_visible_length + wrap_offset; |
if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && |
if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && |
#if 0 |
|
_rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt) |
|
#else |
|
_rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt) |
_rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt) |
#endif |
|
{ |
{ |
#if defined (__MSDOS__) | _rl_cr (); |
putc ('\r', rl_outstream); | |
#else | |
if (_rl_term_cr) | |
tputs (_rl_term_cr, 1, _rl_output_character_function); | |
#endif | |
if (modmark) |
if (modmark) |
_rl_output_some_chars ("*", 1); |
_rl_output_some_chars ("*", 1); |
|
|
_rl_output_some_chars (local_prompt, nleft); |
_rl_output_some_chars (local_prompt, nleft); |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark; |
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark; |
else |
else |
_rl_last_c_pos = nleft + modmark; |
_rl_last_c_pos = nleft + modmark; |
Line 1135 rl_redisplay ()
|
Line 1410 rl_redisplay ()
|
/* Where on that line? And where does that line start |
/* Where on that line? And where does that line start |
in the buffer? */ |
in the buffer? */ |
pos = inv_lbreaks[cursor_linenum]; |
pos = inv_lbreaks[cursor_linenum]; |
/* nleft == number of characters in the line buffer between the | /* nleft == number of characters (bytes) in the line buffer between |
start of the line and the desired cursor position. */ | the start of the line and the desired cursor position. */ |
nleft = cpos_buffer_position - pos; |
nleft = cpos_buffer_position - pos; |
|
|
/* NLEFT is now a number of characters in a buffer. When in a |
/* NLEFT is now a number of characters in a buffer. When in a |
Line 1144 rl_redisplay ()
|
Line 1419 rl_redisplay ()
|
position that doesn't take invisible characters in the prompt |
position that doesn't take invisible characters in the prompt |
into account. We use a fudge factor to compensate. */ |
into account. We use a fudge factor to compensate. */ |
|
|
/* Since _rl_backspace() doesn't know about invisible characters in the | /* Since _rl_backspace() doesn't know about invisible characters in |
prompt, and there's no good way to tell it, we compensate for | the prompt, and there's no good way to tell it, we compensate for |
those characters here and call _rl_backspace() directly. */ | those characters here and call _rl_backspace() directly if |
| necessary */ |
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) |
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) |
{ |
{ |
/* TX == new physical cursor position in multibyte locale. */ |
/* TX == new physical cursor position in multibyte locale. */ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset; |
tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset; |
else |
else |
tx = nleft; |
tx = nleft; |
Line 1165 rl_redisplay ()
|
Line 1441 rl_redisplay ()
|
_rl_last_c_pos as an absolute cursor position, but moving to a |
_rl_last_c_pos as an absolute cursor position, but moving to a |
point specified by a buffer position (NLEFT) that doesn't take |
point specified by a buffer position (NLEFT) that doesn't take |
invisible characters into account. */ |
invisible characters into account. */ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
_rl_move_cursor_relative (nleft, &invisible_line[pos]); | _rl_move_cursor_relative (nleft, &invisible_line[pos], &inv_face[pos]); |
else if (nleft != _rl_last_c_pos) |
else if (nleft != _rl_last_c_pos) |
_rl_move_cursor_relative (nleft, &invisible_line[pos]); | _rl_move_cursor_relative (nleft, &invisible_line[pos], &inv_face[pos]); |
} |
} |
} |
} |
else /* Do horizontal scrolling. */ | else /* Do horizontal scrolling. Much simpler */ |
{ |
{ |
#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0) |
#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0) |
int lmargin, ndisp, nleft, phys_c_pos, t; |
int lmargin, ndisp, nleft, phys_c_pos, t; |
Line 1224 rl_redisplay ()
|
Line 1500 rl_redisplay ()
|
/* If the first character on the screen isn't the first character |
/* If the first character on the screen isn't the first character |
in the display line, indicate this with a special character. */ |
in the display line, indicate this with a special character. */ |
if (lmargin > 0) |
if (lmargin > 0) |
line[lmargin] = '<'; | invisible_line[lmargin] = '<'; |
|
|
/* If SCREENWIDTH characters starting at LMARGIN do not encompass |
/* If SCREENWIDTH characters starting at LMARGIN do not encompass |
the whole line, indicate that with a special character at the |
the whole line, indicate that with a special character at the |
right edge of the screen. If LMARGIN is 0, we need to take the |
right edge of the screen. If LMARGIN is 0, we need to take the |
wrap offset into account. */ |
wrap offset into account. */ |
t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth; |
t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth; |
if (t < out) | if (t > 0 && t < out) |
line[t - 1] = '>'; | invisible_line[t - 1] = '>'; |
|
|
if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin) |
if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin) |
{ |
{ |
forced_display = 0; |
forced_display = 0; |
o_cpos = _rl_last_c_pos; |
o_cpos = _rl_last_c_pos; |
cpos_adjusted = 0; |
cpos_adjusted = 0; |
update_line (&visible_line[last_lmargin], | update_line (&visible_line[last_lmargin], &vis_face[last_lmargin], |
&invisible_line[lmargin], | &invisible_line[lmargin], &inv_face[lmargin], |
0, |
0, |
_rl_screenwidth + visible_wrap_offset, |
_rl_screenwidth + visible_wrap_offset, |
_rl_screenwidth + (lmargin ? 0 : wrap_offset), |
_rl_screenwidth + (lmargin ? 0 : wrap_offset), |
0); |
0); |
|
|
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && | if ((mb_cur_max > 1 && rl_byte_oriented == 0) && |
displaying_prompt_first_line && OLD_CPOS_IN_PROMPT()) |
displaying_prompt_first_line && OLD_CPOS_IN_PROMPT()) |
_rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ |
_rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ |
|
|
Line 1265 rl_redisplay ()
|
Line 1541 rl_redisplay ()
|
if (visible_first_line_len > _rl_screenwidth) |
if (visible_first_line_len > _rl_screenwidth) |
visible_first_line_len = _rl_screenwidth; |
visible_first_line_len = _rl_screenwidth; |
|
|
_rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]); | _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin], &inv_face[lmargin]); |
last_lmargin = lmargin; |
last_lmargin = lmargin; |
} |
} |
} |
} |
Line 1286 rl_redisplay ()
|
Line 1562 rl_redisplay ()
|
visible_wrap_offset = 0; |
visible_wrap_offset = 0; |
else |
else |
visible_wrap_offset = wrap_offset; |
visible_wrap_offset = wrap_offset; |
|
|
|
_rl_quick_redisplay = 0; |
} |
} |
|
|
RL_UNSETSTATE (RL_STATE_REDISPLAYING); |
RL_UNSETSTATE (RL_STATE_REDISPLAYING); |
_rl_release_sigint (); |
_rl_release_sigint (); |
} |
} |
|
|
|
static void |
|
putc_face (int c, int face, char *cur_face) |
|
{ |
|
char cf; |
|
cf = *cur_face; |
|
if (cf != face) |
|
{ |
|
if (cf != FACE_NORMAL && cf != FACE_STANDOUT) |
|
return; |
|
if (face != FACE_NORMAL && face != FACE_STANDOUT) |
|
return; |
|
if (face == FACE_STANDOUT && cf == FACE_NORMAL) |
|
_rl_standout_on (); |
|
if (face == FACE_NORMAL && cf == FACE_STANDOUT) |
|
_rl_standout_off (); |
|
*cur_face = face; |
|
} |
|
if (c != EOF) |
|
putc (c, rl_outstream); |
|
} |
|
|
|
static void |
|
puts_face (const char *str, const char *face, int n) |
|
{ |
|
int i; |
|
char cur_face; |
|
|
|
for (cur_face = FACE_NORMAL, i = 0; i < n; i++) |
|
putc_face (str[i], face[i], &cur_face); |
|
putc_face (EOF, FACE_NORMAL, &cur_face); |
|
} |
|
|
|
static void |
|
norm_face (char *face, int n) |
|
{ |
|
memset (face, FACE_NORMAL, n); |
|
} |
|
|
|
#define ADJUST_CPOS(x) do { _rl_last_c_pos -= (x) ; cpos_adjusted = 1; } while (0) |
|
|
/* PWP: update_line() is based on finding the middle difference of each |
/* PWP: update_line() is based on finding the middle difference of each |
line on the screen; vis: |
line on the screen; vis: |
|
|
/old first difference |
/old first difference |
/beginning of line | /old last same /old EOL | /beginning of line | /old last same /old EOL |
v v v v | v v v v |
old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as |
old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as |
new: eddie> Oh, my little buggy says to me, as lurgid as |
new: eddie> Oh, my little buggy says to me, as lurgid as |
^ ^ ^ ^ | ^ ^ ^ ^ |
\beginning of line | \new last same \new end of line | \beginning of line | \new last same \new end of line |
\new first difference |
\new first difference |
|
|
All are character pointers for the sake of speed. Special cases for |
All are character pointers for the sake of speed. Special cases for |
Line 1309 new: eddie> Oh, my little buggy says to me, as lurgid
|
Line 1627 new: eddie> Oh, my little buggy says to me, as lurgid
|
|
|
Could be made even smarter, but this works well enough */ |
Could be made even smarter, but this works well enough */ |
static void |
static void |
update_line (old, new, current_line, omax, nmax, inv_botlin) | update_line (char *old, char *old_face, char *new, char *new_face, int current_line, int omax, int nmax, int inv_botlin) |
register char *old, *new; | |
int current_line, omax, nmax, inv_botlin; | |
{ |
{ |
register char *ofd, *ols, *oe, *nfd, *nls, *ne; | char *ofd, *ols, *oe, *nfd, *nls, *ne; |
| char *ofdf, *nfdf, *olsf, *nlsf; |
int temp, lendiff, wsatend, od, nd, twidth, o_cpos; |
int temp, lendiff, wsatend, od, nd, twidth, o_cpos; |
int current_invis_chars; |
int current_invis_chars; |
int col_lendiff, col_temp; |
int col_lendiff, col_temp; |
int bytes_to_insert; |
int bytes_to_insert; |
|
int mb_cur_max = MB_CUR_MAX; |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
mbstate_t ps_new, ps_old; |
mbstate_t ps_new, ps_old; |
int new_offset, old_offset; |
int new_offset, old_offset; |
Line 1328 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 1646 update_line (old, new, current_line, omax, nmax, inv_b
|
the exact cursor position and cut-and-paste with certain terminal |
the exact cursor position and cut-and-paste with certain terminal |
emulators. In this calculation, TEMP is the physical screen |
emulators. In this calculation, TEMP is the physical screen |
position of the cursor. */ |
position of the cursor. */ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
temp = _rl_last_c_pos; |
temp = _rl_last_c_pos; |
else |
else |
temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset); |
temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset); |
if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode |
if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode |
&& _rl_last_v_pos == current_line - 1) |
&& _rl_last_v_pos == current_line - 1) |
{ |
{ |
|
/* We're going to wrap around by writing the first character of NEW to |
|
the screen and dealing with changes to what's visible by modifying |
|
OLD to match it. Complicated by the presence of multi-width |
|
characters at the end of the line or beginning of the new one. */ |
|
/* old is always somewhere in visible_line; new is always somewhere in |
|
invisible_line. These should always be null-terminated. */ |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
wchar_t wc; |
wchar_t wc; |
mbstate_t ps; |
mbstate_t ps; |
int tempwidth, bytes; | int oldwidth, newwidth; |
| int oldbytes, newbytes; |
size_t ret; |
size_t ret; |
|
|
/* This fixes only double-column characters, but if the wrapped |
/* This fixes only double-column characters, but if the wrapped |
character consumes more than three columns, spaces will be |
character consumes more than three columns, spaces will be |
inserted in the string buffer. */ |
inserted in the string buffer. */ |
if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0) | /* XXX remember that we are working on the invisible line right now; |
_rl_clear_to_eol (line_state_visible->wrapped_line[current_line]); | we don't swap visible and invisible until just before rl_redisplay |
| returns */ |
| /* This will remove the extra placeholder space we added with |
| _rl_wrapped_multicolumn */ |
| if (current_line < line_state_invisible->wbsize && line_state_invisible->wrapped_line[current_line] > 0) |
| _rl_clear_to_eol (line_state_invisible->wrapped_line[current_line]); |
|
|
|
/* 1. how many screen positions does first char in old consume? */ |
memset (&ps, 0, sizeof (mbstate_t)); |
memset (&ps, 0, sizeof (mbstate_t)); |
ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps); | ret = mbrtowc (&wc, old, mb_cur_max, &ps); |
| oldbytes = ret; |
if (MB_INVALIDCH (ret)) |
if (MB_INVALIDCH (ret)) |
{ |
{ |
tempwidth = 1; | oldwidth = 1; |
ret = 1; | oldbytes = 1; |
} |
} |
else if (MB_NULLWCH (ret)) |
else if (MB_NULLWCH (ret)) |
tempwidth = 0; | oldwidth = 0; |
else |
else |
tempwidth = WCWIDTH (wc); | oldwidth = WCWIDTH (wc); |
| if (oldwidth < 0) |
| oldwidth = 1; |
|
|
if (tempwidth > 0) | /* 2. how many screen positions does the first char in new consume? */ |
| memset (&ps, 0, sizeof (mbstate_t)); |
| ret = mbrtowc (&wc, new, mb_cur_max, &ps); |
| newbytes = ret; |
| if (MB_INVALIDCH (ret)) |
{ |
{ |
int count, i; | newwidth = 1; |
bytes = ret; | newbytes = 1; |
for (count = 0; count < bytes; count++) | } |
putc (new[count], rl_outstream); | else if (MB_NULLWCH (ret)) |
_rl_last_c_pos = tempwidth; | newwidth = 0; |
| else |
| newwidth = WCWIDTH (wc); |
| if (newwidth < 0) |
| newwidth = 1; |
| |
| /* 3. if the new width is less than the old width, we need to keep |
| going in new until we have consumed at least that many screen |
| positions, and figure out how many bytes that will take */ |
| while (newbytes < nmax && newwidth < oldwidth) |
| { |
| int t; |
| |
| ret = mbrtowc (&wc, new+newbytes, mb_cur_max, &ps); |
| if (MB_INVALIDCH (ret)) |
| { |
| newwidth += 1; |
| newbytes += 1; |
| } |
| else if (MB_NULLWCH (ret)) |
| break; |
| else |
| { |
| t = WCWIDTH (wc); |
| newwidth += (t >= 0) ? t : 1; |
| newbytes += ret; |
| } |
| } |
| /* 4. If the new width is more than the old width, keep going in old |
| until we have consumed exactly that many screen positions, and |
| figure out how many bytes that will take. This is an optimization */ |
| while (oldbytes < omax && oldwidth < newwidth) |
| { |
| int t; |
| |
| ret = mbrtowc (&wc, old+oldbytes, mb_cur_max, &ps); |
| if (MB_INVALIDCH (ret)) |
| { |
| oldwidth += 1; |
| oldbytes += 1; |
| } |
| else if (MB_NULLWCH (ret)) |
| break; |
| else |
| { |
| t = WCWIDTH (wc); |
| oldwidth += (t >= 0) ? t : 1; |
| oldbytes += ret; |
| } |
| } |
| /* 5. write the first newbytes of new, which takes newwidth. This is |
| where the screen wrapping takes place, and we are now writing |
| characters onto the new line. We need to fix up old so it |
| accurately reflects what is on the screen after the |
| _rl_output_some_chars below. */ |
| if (newwidth > 0) |
| { |
| int count, i, j; |
| char *optr; |
| |
| puts_face (new, new_face, newbytes); |
| _rl_last_c_pos = newwidth; |
_rl_last_v_pos++; |
_rl_last_v_pos++; |
memset (&ps, 0, sizeof (mbstate_t)); | |
ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps); | /* 5a. If the number of screen positions doesn't match, punt |
if (ret != 0 && bytes != 0) | and do a dumb update. |
| 5b. If the number of bytes is greater in the new line than |
| the old, do a dumb update, because there is no guarantee we |
| can extend the old line enough to fit the new bytes. */ |
| if (newwidth != oldwidth || newbytes > oldbytes) |
{ |
{ |
if (MB_INVALIDCH (ret)) | oe = old + omax; |
ret = 1; | ne = new + nmax; |
memmove (old+bytes, old+ret, strlen (old+ret)); | nd = newbytes; |
memcpy (old, new, bytes); | nfd = new + nd; |
| ofdf = old_face + oldbytes; |
| nfdf = new_face + newbytes; |
| |
| goto dumb_update; |
| } |
| if (oldbytes != 0 && newbytes != 0) |
| { |
| /* We have written as many bytes from new as we need to |
| consume the first character of old. Fix up `old' so it |
| reflects the new screen contents. We use +1 in the |
| memmove call to copy the trailing NUL. */ |
| /* (strlen(old+oldbytes) == (omax - oldbytes - 1)) */ |
| |
| /* Don't bother trying to fit the bytes if the number of bytes |
| doesn't change. */ |
| if (oldbytes != newbytes) |
| { |
| memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1); |
| memmove (old_face+newbytes, old_face+oldbytes, strlen (old+oldbytes) + 1); |
| } |
| memcpy (old, new, newbytes); |
| memcpy (old_face, new_face, newbytes); |
| j = newbytes - oldbytes; |
| omax += j; |
/* Fix up indices if we copy data from one line to another */ |
/* Fix up indices if we copy data from one line to another */ |
omax += bytes - ret; | for (i = current_line+1; j != 0 && i <= inv_botlin+1 && i <=_rl_vis_botlin+1; i++) |
for (i = current_line+1; i <= inv_botlin+1; i++) | vis_lbreaks[i] += j; |
vis_lbreaks[i] += bytes - ret; | |
} |
} |
} |
} |
else |
else |
Line 1389 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 1815 update_line (old, new, current_line, omax, nmax, inv_b
|
_rl_last_c_pos = 1; |
_rl_last_c_pos = 1; |
_rl_last_v_pos++; |
_rl_last_v_pos++; |
if (old[0] && new[0]) |
if (old[0] && new[0]) |
old[0] = new[0]; | { |
| old[0] = new[0]; |
| old_face[0] = new_face[0]; |
| } |
} |
} |
} |
} |
else |
else |
#endif |
#endif |
{ |
{ |
if (new[0]) |
if (new[0]) |
putc (new[0], rl_outstream); | puts_face (new, new_face, 1); |
else |
else |
putc (' ', rl_outstream); |
putc (' ', rl_outstream); |
_rl_last_c_pos = 1; |
_rl_last_c_pos = 1; |
_rl_last_v_pos++; |
_rl_last_v_pos++; |
if (old[0] && new[0]) |
if (old[0] && new[0]) |
old[0] = new[0]; | { |
| old[0] = new[0]; |
| old_face[0] = new_face[0]; |
| } |
} |
} |
} |
} |
|
|
| /* We know that we are dealing with a single screen line here */ |
| if (_rl_quick_redisplay) |
| { |
| nfd = new; |
| nfdf = new_face; |
| ofd = old; |
| ofdf = old_face; |
| for (od = 0, oe = ofd; od < omax && *oe; oe++, od++); |
| for (nd = 0, ne = nfd; nd < nmax && *ne; ne++, nd++); |
| od = nd = 0; |
| _rl_move_cursor_relative (0, old, old_face); |
| |
| bytes_to_insert = ne - nfd; |
| if (bytes_to_insert < local_prompt_len) /* ??? */ |
| goto dumb_update; |
| |
| /* output the prompt, output the line contents, clear the rest */ |
| _rl_output_some_chars (nfd, local_prompt_len); |
| if (mb_cur_max > 1 && rl_byte_oriented == 0) |
| _rl_last_c_pos = prompt_physical_chars; |
| else |
| _rl_last_c_pos = local_prompt_len; |
| |
| bytes_to_insert -= local_prompt_len; |
| if (bytes_to_insert > 0) |
| { |
| puts_face (new+local_prompt_len, nfdf+local_prompt_len, bytes_to_insert); |
| if (mb_cur_max > 1 && rl_byte_oriented) |
| _rl_last_c_pos += _rl_col_width (new, local_prompt_len, ne-new, 1); |
| else |
| _rl_last_c_pos += bytes_to_insert; |
| } |
| |
| /* See comments at dumb_update: for an explanation of this heuristic */ |
| if (nmax < omax) |
| goto clear_rest_of_line; |
| else if ((nmax - W_OFFSET(current_line, wrap_offset)) < (omax - W_OFFSET (current_line, visible_wrap_offset))) |
| goto clear_rest_of_line; |
| else |
| return; |
| } |
| |
/* Find first difference. */ |
/* Find first difference. */ |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
/* See if the old line is a subset of the new line, so that the |
/* See if the old line is a subset of the new line, so that the |
only change is adding characters. */ |
only change is adding characters. */ |
temp = (omax < nmax) ? omax : nmax; |
temp = (omax < nmax) ? omax : nmax; |
if (memcmp (old, new, temp) == 0) /* adding at the end */ | if (memcmp (old, new, temp) == 0 && memcmp (old_face, new_face, temp) == 0) |
{ |
{ |
new_offset = old_offset = temp; | new_offset = old_offset = temp; /* adding at the end */ |
ofd = old + temp; |
ofd = old + temp; |
|
ofdf = old_face + temp; |
nfd = new + temp; |
nfd = new + temp; |
|
nfdf = new_face + temp; |
} |
} |
else |
else |
{ |
{ |
memset (&ps_new, 0, sizeof(mbstate_t)); |
memset (&ps_new, 0, sizeof(mbstate_t)); |
memset (&ps_old, 0, sizeof(mbstate_t)); |
memset (&ps_old, 0, sizeof(mbstate_t)); |
|
|
if (omax == nmax && STREQN (new, old, omax)) | /* Are the old and new lines the same? */ |
| if (omax == nmax && memcmp (new, old, omax) == 0 && memcmp (new_face, old_face, omax) == 0) |
{ |
{ |
old_offset = omax; |
old_offset = omax; |
new_offset = nmax; |
new_offset = nmax; |
ofd = old + omax; |
ofd = old + omax; |
|
ofdf = old_face + omax; |
nfd = new + nmax; |
nfd = new + nmax; |
|
nfdf = new_face + nmax; |
} |
} |
else |
else |
{ |
{ |
|
/* Go through the line from the beginning and find the first |
|
difference. We assume that faces change at (possibly multi- |
|
byte) character boundaries. */ |
new_offset = old_offset = 0; |
new_offset = old_offset = 0; |
for (ofd = old, nfd = new; | for (ofd = old, ofdf = old_face, nfd = new, nfdf = new_face; |
(ofd - old < omax) && *ofd && |
(ofd - old < omax) && *ofd && |
_rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); ) | _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new) && |
| *ofdf == *nfdf; ) |
{ |
{ |
old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY); |
old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY); |
new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY); |
new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY); |
|
|
ofd = old + old_offset; |
ofd = old + old_offset; |
|
ofdf = old_face + old_offset; |
nfd = new + new_offset; |
nfd = new + new_offset; |
|
nfdf = new_face + new_offset; |
} |
} |
} |
} |
} |
} |
} |
} |
else |
else |
#endif |
#endif |
for (ofd = old, nfd = new; | for (ofd = old, ofdf = old_face, nfd = new, nfdf = new_face; |
(ofd - old < omax) && *ofd && (*ofd == *nfd); | (ofd - old < omax) && *ofd && (*ofd == *nfd) && (*ofdf == *nfdf); |
ofd++, nfd++) | ofd++, nfd++, ofdf++, nfdf++) |
; |
; |
|
|
/* Move to the end of the screen line. ND and OD are used to keep track |
/* Move to the end of the screen line. ND and OD are used to keep track |
Line 1466 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 1950 update_line (old, new, current_line, omax, nmax, inv_b
|
return; |
return; |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_utf8locale) | if (mb_cur_max > 1 && rl_byte_oriented == 0 && _rl_utf8locale) |
{ |
{ |
wchar_t wc; |
wchar_t wc; |
mbstate_t ps = { 0 }; |
mbstate_t ps = { 0 }; |
Line 1475 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 1959 update_line (old, new, current_line, omax, nmax, inv_b
|
/* If the first character in the difference is a zero-width character, |
/* If the first character in the difference is a zero-width character, |
assume it's a combining character and back one up so the two base |
assume it's a combining character and back one up so the two base |
characters no longer compare equivalently. */ |
characters no longer compare equivalently. */ |
t = mbrtowc (&wc, ofd, MB_CUR_MAX, &ps); | t = mbrtowc (&wc, ofd, mb_cur_max, &ps); |
if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0) |
if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0) |
{ |
{ |
old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY); |
old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY); |
new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY); |
new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY); |
ofd = old + old_offset; /* equal by definition */ |
ofd = old + old_offset; /* equal by definition */ |
|
ofdf = old_face + old_offset; |
nfd = new + new_offset; |
nfd = new + new_offset; |
|
nfdf = new_face + new_offset; |
} |
} |
} |
} |
#endif |
#endif |
Line 1489 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 1975 update_line (old, new, current_line, omax, nmax, inv_b
|
wsatend = 1; /* flag for trailing whitespace */ |
wsatend = 1; /* flag for trailing whitespace */ |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | /* Find the last character that is the same between the two lines. This |
| bounds the region that needs to change. */ |
| if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY); |
ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY); |
|
olsf = old_face + (ols - old); |
nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY); |
nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY); |
|
nlsf = new_face + (nls - new); |
|
|
while ((ols > ofd) && (nls > nfd)) |
while ((ols > ofd) && (nls > nfd)) |
{ |
{ |
memset (&ps_old, 0, sizeof (mbstate_t)); |
memset (&ps_old, 0, sizeof (mbstate_t)); |
memset (&ps_new, 0, sizeof (mbstate_t)); |
memset (&ps_new, 0, sizeof (mbstate_t)); |
|
|
#if 0 | if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0 || |
/* On advice from jir@yamato.ibm.com */ | *olsf != *nlsf) |
_rl_adjust_point (old, ols - old, &ps_old); | |
_rl_adjust_point (new, nls - new, &ps_new); | |
#endif | |
| |
if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0) | |
break; |
break; |
|
|
if (*ols == ' ') |
if (*ols == ' ') |
wsatend = 0; |
wsatend = 0; |
|
|
ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY); |
ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY); |
|
olsf = old_face + (ols - old); |
nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY); |
nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY); |
|
nlsf = new_face + (nls - new); |
} |
} |
} |
} |
else |
else |
{ |
{ |
#endif /* HANDLE_MULTIBYTE */ |
#endif /* HANDLE_MULTIBYTE */ |
ols = oe - 1; /* find last same */ |
ols = oe - 1; /* find last same */ |
|
olsf = old_face + (ols - old); |
nls = ne - 1; |
nls = ne - 1; |
while ((ols > ofd) && (nls > nfd) && (*ols == *nls)) | nlsf = new_face + (nls - new); |
| while ((ols > ofd) && (nls > nfd) && (*ols == *nls) && (*olsf == *nlsf)) |
{ |
{ |
if (*ols != ' ') |
if (*ols != ' ') |
wsatend = 0; |
wsatend = 0; |
ols--; | ols--; olsf--; |
nls--; | nls--; nlsf--; |
} |
} |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
} |
} |
Line 1534 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2023 update_line (old, new, current_line, omax, nmax, inv_b
|
if (wsatend) |
if (wsatend) |
{ |
{ |
ols = oe; |
ols = oe; |
|
olsf = old_face + (ols - old); |
nls = ne; |
nls = ne; |
|
nlsf = new_face + (nls - new); |
} |
} |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
/* This may not work for stateful encoding, but who cares? To handle |
/* This may not work for stateful encoding, but who cares? To handle |
stateful encoding properly, we have to scan each string from the |
stateful encoding properly, we have to scan each string from the |
beginning and compare. */ |
beginning and compare. */ |
else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0) | else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0 || *olsf != *nlsf) |
#else |
#else |
else if (*ols != *nls) | else if (*ols != *nls || *olsf != *nlsf) |
#endif |
#endif |
{ |
{ |
if (*ols) /* don't step past the NUL */ |
if (*ols) /* don't step past the NUL */ |
{ |
{ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY); |
ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY); |
else |
else |
ols++; |
ols++; |
} |
} |
if (*nls) |
if (*nls) |
{ |
{ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY); |
nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY); |
else |
else |
nls++; |
nls++; |
} |
} |
|
olsf = old_face + (ols - old); |
|
nlsf = new_face + (nls - new); |
} |
} |
|
|
/* count of invisible characters in the current invisible line. */ |
/* count of invisible characters in the current invisible line. */ |
Line 1566 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2059 update_line (old, new, current_line, omax, nmax, inv_b
|
if (_rl_last_v_pos != current_line) |
if (_rl_last_v_pos != current_line) |
{ |
{ |
_rl_move_vert (current_line); |
_rl_move_vert (current_line); |
if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset) | /* We have moved up to a new screen line. This line may or may not have |
| invisible characters on it, but we do our best to recalculate |
| visible_wrap_offset based on what we know. */ |
| if (current_line == 0) |
| visible_wrap_offset = prompt_invis_chars_first_line; /* XXX */ |
| #if 0 /* XXX - not yet */ |
| else if (current_line == prompt_last_screen_line && wrap_offset > prompt_invis_chars_first_line) |
| visible_wrap_offset = wrap_offset - prompt_invis_chars_first_line |
| #endif |
| if ((mb_cur_max == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset) |
_rl_last_c_pos += visible_wrap_offset; |
_rl_last_c_pos += visible_wrap_offset; |
} |
} |
|
|
Line 1577 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2079 update_line (old, new, current_line, omax, nmax, inv_b
|
string, then redraw the entire prompt string. We can only do this |
string, then redraw the entire prompt string. We can only do this |
reliably if the terminal supports a `cr' capability. |
reliably if the terminal supports a `cr' capability. |
|
|
|
This can also happen if the prompt string has changed, and the first |
|
difference in the line is in the middle of the prompt string, after a |
|
sequence of invisible characters (worst case) and before the end of |
|
the prompt. In this case, we have to redraw the entire prompt string |
|
so that the entire sequence of invisible characters is drawn. We need |
|
to handle the worst case, when the difference is after (or in the middle |
|
of) a sequence of invisible characters that changes the text color and |
|
before the sequence that restores the text color to normal. Then we have |
|
to make sure that the lines still differ -- if they don't, we can |
|
return immediately. |
|
|
This is not an efficiency hack -- there is a problem with redrawing |
This is not an efficiency hack -- there is a problem with redrawing |
portions of the prompt string if they contain terminal escape |
portions of the prompt string if they contain terminal escape |
sequences (like drawing the `unbold' sequence without a corresponding |
sequences (like drawing the `unbold' sequence without a corresponding |
`bold') that manifests itself on certain terminals. */ |
`bold') that manifests itself on certain terminals. */ |
|
|
lendiff = local_prompt_len; |
lendiff = local_prompt_len; |
|
if (lendiff > nmax) |
|
lendiff = nmax; |
od = ofd - old; /* index of first difference in visible line */ |
od = ofd - old; /* index of first difference in visible line */ |
|
nd = nfd - new; /* nd, od are buffer indexes */ |
if (current_line == 0 && !_rl_horizontal_scroll_mode && |
if (current_line == 0 && !_rl_horizontal_scroll_mode && |
_rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 && |
_rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 && |
od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX) | (((od > 0 || nd > 0) && (od <= prompt_last_invisible || nd <= prompt_last_invisible)) || |
| ((od >= lendiff) && _rl_last_c_pos < PROMPT_ENDING_INDEX))) |
{ |
{ |
#if defined (__MSDOS__) | _rl_cr (); |
putc ('\r', rl_outstream); | |
#else | |
tputs (_rl_term_cr, 1, _rl_output_character_function); | |
#endif | |
if (modmark) |
if (modmark) |
_rl_output_some_chars ("*", 1); |
_rl_output_some_chars ("*", 1); |
_rl_output_some_chars (local_prompt, lendiff); |
_rl_output_some_chars (local_prompt, lendiff); |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
/* We take wrap_offset into account here so we can pass correct | /* If we just output the entire prompt string we can take advantage |
information to _rl_move_cursor_relative. */ | of knowing the number of physical characters in the prompt. If |
_rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark; | the prompt wraps lines (lendiff clamped at nmax), we can't. */ |
| if (lendiff == local_prompt_len) |
| _rl_last_c_pos = prompt_physical_chars + modmark; |
| else |
| /* We take wrap_offset into account here so we can pass correct |
| information to _rl_move_cursor_relative. */ |
| _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark; |
cpos_adjusted = 1; |
cpos_adjusted = 1; |
} |
} |
else |
else |
_rl_last_c_pos = lendiff + modmark; |
_rl_last_c_pos = lendiff + modmark; |
|
|
|
/* Now if we have printed the prompt string because the first difference |
|
was within the prompt, see if we need to recompute where the lines |
|
differ. Check whether where we are now is past the last place where |
|
the old and new lines are the same and short-circuit now if we are. */ |
|
if ((od <= prompt_last_invisible || nd <= prompt_last_invisible) && |
|
omax == nmax && |
|
lendiff > (ols-old) && lendiff > (nls-new)) |
|
return; |
|
|
|
/* XXX - we need to fix up our calculations if we are now past the |
|
old ofd/nfd and the prompt length (or line length) has changed. |
|
We punt on the problem and do a dumb update. We'd like to be able |
|
to just output the prompt from the beginning of the line up to the |
|
first difference, but you don't know the number of invisible |
|
characters in that case. |
|
This needs a lot of work to be efficient, but it usually doesn't matter. */ |
|
if ((od <= prompt_last_invisible || nd <= prompt_last_invisible)) |
|
{ |
|
nfd = new + lendiff; /* number of characters we output above */ |
|
nfdf = new_face + lendiff; |
|
nd = lendiff; |
|
|
|
/* Do a dumb update and return */ |
|
dumb_update: |
|
temp = ne - nfd; |
|
if (temp > 0) |
|
{ |
|
puts_face (nfd, nfdf, temp); |
|
if (mb_cur_max > 1 && rl_byte_oriented == 0) |
|
{ |
|
_rl_last_c_pos += _rl_col_width (new, nd, ne - new, 1); |
|
/* Need to adjust here based on wrap_offset. Guess that if |
|
this is the line containing the last line of the prompt |
|
we need to adjust by |
|
wrap_offset-prompt_invis_chars_first_line |
|
on the assumption that this is the number of invisible |
|
characters in the last line of the prompt. */ |
|
if (wrap_offset > prompt_invis_chars_first_line && |
|
current_line == prompt_last_screen_line && |
|
prompt_physical_chars > _rl_screenwidth && |
|
_rl_horizontal_scroll_mode == 0) |
|
ADJUST_CPOS (wrap_offset - prompt_invis_chars_first_line); |
|
|
|
/* If we just output a new line including the prompt, and |
|
the prompt includes invisible characters, we need to |
|
account for them in the _rl_last_c_pos calculation, since |
|
_rl_col_width does not. This happens when other code does |
|
a goto dumb_update; */ |
|
else if (current_line == 0 && |
|
nfd == new && |
|
prompt_invis_chars_first_line && |
|
local_prompt_len <= temp && |
|
wrap_offset >= prompt_invis_chars_first_line && |
|
_rl_horizontal_scroll_mode == 0) |
|
ADJUST_CPOS (prompt_invis_chars_first_line); |
|
} |
|
else |
|
_rl_last_c_pos += temp; |
|
} |
|
/* This is a useful heuristic, but what we really want is to clear |
|
if the new number of visible screen characters is less than the |
|
old number of visible screen characters. If the prompt has changed, |
|
we don't really have enough information about the visible line to |
|
know for sure, so we use another heuristic calclulation below. */ |
|
if (nmax < omax) |
|
goto clear_rest_of_line; /* XXX */ |
|
else if ((nmax - W_OFFSET(current_line, wrap_offset)) < (omax - W_OFFSET (current_line, visible_wrap_offset))) |
|
goto clear_rest_of_line; |
|
else |
|
return; |
|
} |
} |
} |
|
|
o_cpos = _rl_last_c_pos; |
o_cpos = _rl_last_c_pos; |
Line 1612 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2203 update_line (old, new, current_line, omax, nmax, inv_b
|
/* When this function returns, _rl_last_c_pos is correct, and an absolute |
/* When this function returns, _rl_last_c_pos is correct, and an absolute |
cursor position in multibyte mode, but a buffer index when not in a |
cursor position in multibyte mode, but a buffer index when not in a |
multibyte locale. */ |
multibyte locale. */ |
_rl_move_cursor_relative (od, old); | _rl_move_cursor_relative (od, old, old_face); |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
/* We need to indicate that the cursor position is correct in the presence of |
/* We need to indicate that the cursor position is correct in the presence of |
invisible characters in the prompt string. Let's see if setting this when |
invisible characters in the prompt string. Let's see if setting this when |
we make sure we're at the end of the drawn prompt string works. */ |
we make sure we're at the end of the drawn prompt string works. */ |
if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && | if (current_line == 0 && mb_cur_max > 1 && rl_byte_oriented == 0 && |
(_rl_last_c_pos > 0 || o_cpos > 0) && |
(_rl_last_c_pos > 0 || o_cpos > 0) && |
_rl_last_c_pos == prompt_physical_chars) |
_rl_last_c_pos == prompt_physical_chars) |
cpos_adjusted = 1; |
cpos_adjusted = 1; |
Line 1629 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2220 update_line (old, new, current_line, omax, nmax, inv_b
|
col_lendiff == difference on screen (columns) |
col_lendiff == difference on screen (columns) |
When not using multibyte characters, these are equal */ |
When not using multibyte characters, these are equal */ |
lendiff = (nls - nfd) - (ols - ofd); |
lendiff = (nls - nfd) - (ols - ofd); |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1); | { |
| int newchars, newwidth, newind; |
| int oldchars, oldwidth, oldind; |
| |
| newchars = nls - new; |
| oldchars = ols - old; |
| |
| /* If we can do it, try to adjust nls and ols so that nls-new will |
| contain the entire new prompt string. That way we can use |
| prompt_physical_chars and not have to recompute column widths. |
| _rl_col_width adds wrap_offset and expects the caller to compensate, |
| which we do below, so we do the same thing if we don't call |
| _rl_col_width. |
| We don't have to compare, since we know the characters are the same. |
| The check of differing numbers of invisible chars may be extraneous. |
| XXX - experimental */ |
| if (current_line == 0 && nfd == new && newchars > prompt_last_invisible && |
| newchars <= local_prompt_len && |
| local_prompt_len <= nmax && |
| current_invis_chars != visible_wrap_offset) |
| { |
| while (newchars < nmax && oldchars < omax && newchars < local_prompt_len) |
| { |
| #if defined (HANDLE_MULTIBYTE) |
| newind = _rl_find_next_mbchar (new, newchars, 1, MB_FIND_NONZERO); |
| oldind = _rl_find_next_mbchar (old, oldchars, 1, MB_FIND_NONZERO); |
| |
| nls += newind - newchars; |
| ols += oldind - oldchars; |
| |
| newchars = newind; |
| oldchars = oldind; |
| #else |
| nls++; ols++; |
| newchars++; oldchars++; |
| #endif |
| } |
| newwidth = (newchars == local_prompt_len) ? prompt_physical_chars + wrap_offset |
| : _rl_col_width (new, 0, nls - new, 1); |
| /* if we changed nls and ols, we need to recompute lendiff */ |
| lendiff = (nls - nfd) - (ols - ofd); |
| |
| nlsf = new_face + (nls - new); |
| olsf = old_face + (ols - old); |
| } |
| else |
| newwidth = _rl_col_width (new, nfd - new, nls - new, 1); |
| |
| oldwidth = _rl_col_width (old, ofd - old, ols - old, 1); |
| |
| col_lendiff = newwidth - oldwidth; |
| } |
else |
else |
col_lendiff = lendiff; |
col_lendiff = lendiff; |
|
|
|
/* col_lendiff uses _rl_col_width(), which doesn't know about whether or not |
|
the multibyte characters it counts are invisible, so unless we're printing |
|
the entire prompt string (in which case we can use prompt_physical_chars) |
|
the count is short by the number of bytes in the invisible multibyte |
|
characters - the number of multibyte characters. |
|
|
|
We don't have a good way to solve this without moving to something like |
|
a bitmap that indicates which characters are visible and which are |
|
invisible. We fix it up (imperfectly) in the caller and by trying to use |
|
the entire prompt string wherever we can. */ |
|
|
/* If we are changing the number of invisible characters in a line, and |
/* If we are changing the number of invisible characters in a line, and |
the spot of first difference is before the end of the invisible chars, |
the spot of first difference is before the end of the invisible chars, |
lendiff needs to be adjusted. */ |
lendiff needs to be adjusted. */ |
if (current_line == 0 && /* !_rl_horizontal_scroll_mode && */ | if (current_line == 0 && current_invis_chars != visible_wrap_offset) |
current_invis_chars != visible_wrap_offset) | |
{ |
{ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
lendiff += visible_wrap_offset - current_invis_chars; |
lendiff += visible_wrap_offset - current_invis_chars; |
col_lendiff += visible_wrap_offset - current_invis_chars; |
col_lendiff += visible_wrap_offset - current_invis_chars; |
Line 1658 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2310 update_line (old, new, current_line, omax, nmax, inv_b
|
and writes TEMP bytes. */ |
and writes TEMP bytes. */ |
/* Insert (diff (len (old), len (new)) ch. */ |
/* Insert (diff (len (old), len (new)) ch. */ |
temp = ne - nfd; |
temp = ne - nfd; |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
col_temp = _rl_col_width (new, nfd - new, ne - new, 1); |
col_temp = _rl_col_width (new, nfd - new, ne - new, 1); |
else |
else |
col_temp = temp; |
col_temp = temp; |
Line 1671 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2323 update_line (old, new, current_line, omax, nmax, inv_b
|
{ |
{ |
/* Non-zero if we're increasing the number of lines. */ |
/* Non-zero if we're increasing the number of lines. */ |
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin; |
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin; |
|
|
/* If col_lendiff is > 0, implying that the new string takes up more |
/* If col_lendiff is > 0, implying that the new string takes up more |
screen real estate than the old, but lendiff is < 0, meaning that it |
screen real estate than the old, but lendiff is < 0, meaning that it |
takes fewer bytes, we need to just output the characters starting |
takes fewer bytes, we need to just output the characters starting |
Line 1679 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2332 update_line (old, new, current_line, omax, nmax, inv_b
|
only happen in a multibyte environment. */ |
only happen in a multibyte environment. */ |
if (lendiff < 0) |
if (lendiff < 0) |
{ |
{ |
_rl_output_some_chars (nfd, temp); | puts_face (nfd, nfdf, temp); |
_rl_last_c_pos += col_temp; /* XXX - was _rl_col_width (nfd, 0, temp, 1); */ | _rl_last_c_pos += col_temp; |
/* If nfd begins before any invisible characters in the prompt, |
/* If nfd begins before any invisible characters in the prompt, |
adjust _rl_last_c_pos to account for wrap_offset and set |
adjust _rl_last_c_pos to account for wrap_offset and set |
cpos_adjusted to let the caller know. */ |
cpos_adjusted to let the caller know. */ |
if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) |
if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) |
{ | ADJUST_CPOS (wrap_offset); /* XXX - prompt_invis_chars_first_line? */ |
_rl_last_c_pos -= wrap_offset; | |
cpos_adjusted = 1; | |
} | |
return; |
return; |
} |
} |
/* Sometimes it is cheaper to print the characters rather than |
/* Sometimes it is cheaper to print the characters rather than |
Line 1709 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2359 update_line (old, new, current_line, omax, nmax, inv_b
|
_rl_last_c_pos == 0 && |
_rl_last_c_pos == 0 && |
lendiff > prompt_visible_length && |
lendiff > prompt_visible_length && |
current_invis_chars > 0) == 0) && |
current_invis_chars > 0) == 0) && |
(((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && | (((mb_cur_max > 1 && rl_byte_oriented == 0) && |
current_line == 0 && wrap_offset && |
current_line == 0 && wrap_offset && |
((nfd - new) <= prompt_last_invisible) && |
((nfd - new) <= prompt_last_invisible) && |
(col_lendiff < prompt_visible_length)) == 0) && |
(col_lendiff < prompt_visible_length)) == 0) && |
(visible_wrap_offset >= current_invis_chars)) |
(visible_wrap_offset >= current_invis_chars)) |
{ |
{ |
open_some_spaces (col_lendiff); |
open_some_spaces (col_lendiff); |
_rl_output_some_chars (nfd, bytes_to_insert); | puts_face (nfd, nfdf, bytes_to_insert); |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); |
_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); |
else |
else |
_rl_last_c_pos += bytes_to_insert; |
_rl_last_c_pos += bytes_to_insert; |
} |
} |
else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0) | else if ((mb_cur_max == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0) |
{ |
{ |
/* At the end of a line the characters do not have to |
/* At the end of a line the characters do not have to |
be "inserted". They can just be placed on the screen. */ |
be "inserted". They can just be placed on the screen. */ |
_rl_output_some_chars (nfd, temp); | puts_face (nfd, nfdf, temp); |
_rl_last_c_pos += col_temp; |
_rl_last_c_pos += col_temp; |
return; |
return; |
} |
} |
else /* just write from first difference to end of new line */ |
else /* just write from first difference to end of new line */ |
{ |
{ |
_rl_output_some_chars (nfd, temp); | puts_face (nfd, nfdf, temp); |
_rl_last_c_pos += col_temp; |
_rl_last_c_pos += col_temp; |
/* If nfd begins before the last invisible character in the |
/* If nfd begins before the last invisible character in the |
prompt, adjust _rl_last_c_pos to account for wrap_offset |
prompt, adjust _rl_last_c_pos to account for wrap_offset |
and set cpos_adjusted to let the caller know. */ |
and set cpos_adjusted to let the caller know. */ |
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) | if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) |
{ | ADJUST_CPOS (wrap_offset); /* XXX - prompt_invis_chars_first_line? */ |
_rl_last_c_pos -= wrap_offset; | |
cpos_adjusted = 1; | |
} | |
return; |
return; |
} |
} |
|
|
Line 1750 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2397 update_line (old, new, current_line, omax, nmax, inv_b
|
/* If nfd begins before the last invisible character in the |
/* If nfd begins before the last invisible character in the |
prompt, adjust _rl_last_c_pos to account for wrap_offset |
prompt, adjust _rl_last_c_pos to account for wrap_offset |
and set cpos_adjusted to let the caller know. */ |
and set cpos_adjusted to let the caller know. */ |
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) | if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) |
{ | ADJUST_CPOS (wrap_offset); /* XXX - prompt_invis_chars_first_line? */ |
_rl_last_c_pos -= wrap_offset; | |
cpos_adjusted = 1; | |
} | |
} |
} |
} |
} |
else |
else |
{ |
{ |
/* cannot insert chars, write to EOL */ |
/* cannot insert chars, write to EOL */ |
_rl_output_some_chars (nfd, temp); | puts_face (nfd, nfdf, temp); |
_rl_last_c_pos += col_temp; |
_rl_last_c_pos += col_temp; |
/* If we're in a multibyte locale and were before the last invisible |
/* If we're in a multibyte locale and were before the last invisible |
char in the current line (which implies we just output some invisible |
char in the current line (which implies we just output some invisible |
characters) we need to adjust _rl_last_c_pos, since it represents |
characters) we need to adjust _rl_last_c_pos, since it represents |
a physical character position. */ |
a physical character position. */ |
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && | /* The current_line*rl_screenwidth+prompt_invis_chars_first_line is a |
| crude attempt to compute how far into the new line buffer we are. |
| It doesn't work well in the face of multibyte characters and needs |
| to be rethought. XXX */ |
| if ((mb_cur_max > 1 && rl_byte_oriented == 0) && |
current_line == prompt_last_screen_line && wrap_offset && |
current_line == prompt_last_screen_line && wrap_offset && |
displaying_prompt_first_line && |
displaying_prompt_first_line && |
wrap_offset != prompt_invis_chars_first_line && |
wrap_offset != prompt_invis_chars_first_line && |
((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth)))) | ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth+prompt_invis_chars_first_line)))) |
{ | ADJUST_CPOS (wrap_offset - prompt_invis_chars_first_line); |
_rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line; | |
cpos_adjusted = 1; | /* XXX - what happens if wrap_offset == prompt_invis_chars_first_line |
} | and we are drawing the first line (current_line == 0)? We should |
| adjust by _rl_last_c_pos -= prompt_invis_chars_first_line */ |
} |
} |
} |
} |
else /* Delete characters from line. */ |
else /* Delete characters from line. */ |
Line 1809 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2458 update_line (old, new, current_line, omax, nmax, inv_b
|
characters in the prompt, we need to adjust _rl_last_c_pos |
characters in the prompt, we need to adjust _rl_last_c_pos |
in a multibyte locale to account for the wrap offset and |
in a multibyte locale to account for the wrap offset and |
set cpos_adjusted accordingly. */ |
set cpos_adjusted accordingly. */ |
_rl_output_some_chars (nfd, bytes_to_insert); | puts_face (nfd, nfdf, bytes_to_insert); |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
|
/* This still doesn't take into account whether or not the |
|
characters that this counts are invisible. */ |
_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); |
_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); |
if (current_line == 0 && wrap_offset && |
if (current_line == 0 && wrap_offset && |
displaying_prompt_first_line && |
displaying_prompt_first_line && |
_rl_last_c_pos > wrap_offset && | prompt_invis_chars_first_line && |
| _rl_last_c_pos >= prompt_invis_chars_first_line && |
((nfd - new) <= prompt_last_invisible)) |
((nfd - new) <= prompt_last_invisible)) |
{ | ADJUST_CPOS (prompt_invis_chars_first_line); |
_rl_last_c_pos -= wrap_offset; | |
cpos_adjusted = 1; | #if 1 |
} | #ifdef HANDLE_MULTIBYTE |
| /* If we write a non-space into the last screen column, |
| remove the note that we added a space to compensate for |
| a multibyte double-width character that didn't fit, since |
| it's only valid for what was previously there. */ |
| /* XXX - watch this */ |
| if (_rl_last_c_pos == _rl_screenwidth && |
| line_state_invisible->wrapped_line[current_line+1] && |
| nfd[bytes_to_insert-1] != ' ') |
| line_state_invisible->wrapped_line[current_line+1] = 0; |
| #endif |
| #endif |
} |
} |
else |
else |
_rl_last_c_pos += bytes_to_insert; |
_rl_last_c_pos += bytes_to_insert; |
Line 1829 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2492 update_line (old, new, current_line, omax, nmax, inv_b
|
so we move there with _rl_move_cursor_relative */ |
so we move there with _rl_move_cursor_relative */ |
if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new))) |
if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new))) |
{ |
{ |
_rl_move_cursor_relative (ne-new, new); | _rl_move_cursor_relative (ne-new, new, new_face); |
goto clear_rest_of_line; |
goto clear_rest_of_line; |
} |
} |
} |
} |
Line 1843 update_line (old, new, current_line, omax, nmax, inv_b
|
Line 2506 update_line (old, new, current_line, omax, nmax, inv_b
|
characters in the prompt, we need to adjust _rl_last_c_pos |
characters in the prompt, we need to adjust _rl_last_c_pos |
in a multibyte locale to account for the wrap offset and |
in a multibyte locale to account for the wrap offset and |
set cpos_adjusted accordingly. */ |
set cpos_adjusted accordingly. */ |
_rl_output_some_chars (nfd, temp); | puts_face (nfd, nfdf, temp); |
_rl_last_c_pos += col_temp; /* XXX */ |
_rl_last_c_pos += col_temp; /* XXX */ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
if (current_line == 0 && wrap_offset && |
if (current_line == 0 && wrap_offset && |
displaying_prompt_first_line && |
displaying_prompt_first_line && |
_rl_last_c_pos > wrap_offset && |
_rl_last_c_pos > wrap_offset && |
((nfd - new) <= prompt_last_invisible)) |
((nfd - new) <= prompt_last_invisible)) |
{ | ADJUST_CPOS (wrap_offset); /* XXX - prompt_invis_chars_first_line? */ |
_rl_last_c_pos -= wrap_offset; | |
cpos_adjusted = 1; | |
} | |
} |
} |
} |
} |
clear_rest_of_line: |
clear_rest_of_line: |
lendiff = (oe - old) - (ne - new); |
lendiff = (oe - old) - (ne - new); |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1); |
col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1); |
else |
else |
col_lendiff = lendiff; |
col_lendiff = lendiff; |
Line 1869 clear_rest_of_line:
|
Line 2529 clear_rest_of_line:
|
space_to_eol will insert too many spaces. XXX - maybe we should |
space_to_eol will insert too many spaces. XXX - maybe we should |
adjust col_lendiff based on the difference between _rl_last_c_pos |
adjust col_lendiff based on the difference between _rl_last_c_pos |
and _rl_screenwidth */ |
and _rl_screenwidth */ |
if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth))) | if (col_lendiff && ((mb_cur_max == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth))) |
{ |
{ |
if (_rl_term_autowrap && current_line < inv_botlin) |
if (_rl_term_autowrap && current_line < inv_botlin) |
space_to_eol (col_lendiff); |
space_to_eol (col_lendiff); |
Line 1882 clear_rest_of_line:
|
Line 2542 clear_rest_of_line:
|
|
|
/* Tell the update routines that we have moved onto a new (empty) line. */ |
/* Tell the update routines that we have moved onto a new (empty) line. */ |
int |
int |
rl_on_new_line () | rl_on_new_line (void) |
{ |
{ |
if (visible_line) |
if (visible_line) |
visible_line[0] = '\0'; |
visible_line[0] = '\0'; |
Line 1895 rl_on_new_line ()
|
Line 2555 rl_on_new_line ()
|
return 0; |
return 0; |
} |
} |
|
|
|
/* Clear all screen lines occupied by the current readline line buffer |
|
(visible line) */ |
|
int |
|
rl_clear_visible_line (void) |
|
{ |
|
int curr_line; |
|
|
|
/* Make sure we move to column 0 so we clear the entire line */ |
|
_rl_cr (); |
|
_rl_last_c_pos = 0; |
|
|
|
/* Move to the last screen line of the current visible line */ |
|
_rl_move_vert (_rl_vis_botlin); |
|
|
|
/* And erase screen lines going up to line 0 (first visible line) */ |
|
for (curr_line = _rl_last_v_pos; curr_line >= 0; curr_line--) |
|
{ |
|
_rl_move_vert (curr_line); |
|
_rl_clear_to_eol (0); |
|
} |
|
|
|
return 0; |
|
} |
|
|
/* Tell the update routines that we have moved onto a new line with the |
/* Tell the update routines that we have moved onto a new line with the |
prompt already displayed. Code originally from the version of readline |
prompt already displayed. Code originally from the version of readline |
distributed with CLISP. rl_expand_prompt must have already been called |
distributed with CLISP. rl_expand_prompt must have already been called |
(explicitly or implicitly). This still doesn't work exactly right. */ | (explicitly or implicitly). This still doesn't work exactly right; it |
| should use expand_prompt() */ |
int |
int |
rl_on_new_line_with_prompt () | rl_on_new_line_with_prompt (void) |
{ |
{ |
int prompt_size, i, l, real_screenwidth, newlines; |
int prompt_size, i, l, real_screenwidth, newlines; |
char *prompt_last_line, *lprompt; |
char *prompt_last_line, *lprompt; |
Line 1956 rl_on_new_line_with_prompt ()
|
Line 2641 rl_on_new_line_with_prompt ()
|
|
|
/* Actually update the display, period. */ |
/* Actually update the display, period. */ |
int |
int |
rl_forced_update_display () | rl_forced_update_display (void) |
{ |
{ |
register char *temp; |
register char *temp; |
|
|
Line 1972 rl_forced_update_display ()
|
Line 2657 rl_forced_update_display ()
|
return 0; |
return 0; |
} |
} |
|
|
|
/* Redraw only the last line of a multi-line prompt. */ |
|
void |
|
rl_redraw_prompt_last_line (void) |
|
{ |
|
char *t; |
|
|
|
t = strrchr (rl_display_prompt, '\n'); |
|
if (t) |
|
redraw_prompt (++t); |
|
else |
|
rl_forced_update_display (); |
|
} |
|
|
/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices. |
/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices. |
(Well, when we don't have multibyte characters, _rl_last_c_pos is a |
(Well, when we don't have multibyte characters, _rl_last_c_pos is a |
buffer index.) |
buffer index.) |
DATA is the contents of the screen line of interest; i.e., where |
DATA is the contents of the screen line of interest; i.e., where |
the movement is being done. */ | the movement is being done. |
void | DATA is always the visible line or the invisible line */ |
_rl_move_cursor_relative (new, data) | static void |
int new; | _rl_move_cursor_relative (int new, const char *data, const char *dataf) |
const char *data; | |
{ |
{ |
register int i; |
register int i; |
int woff; /* number of invisible chars on current line */ |
int woff; /* number of invisible chars on current line */ |
int cpos, dpos; /* current and desired cursor positions */ |
int cpos, dpos; /* current and desired cursor positions */ |
int adjust; |
int adjust; |
|
int in_invisline; |
|
int mb_cur_max = MB_CUR_MAX; |
|
|
woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset); |
woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset); |
cpos = _rl_last_c_pos; |
cpos = _rl_last_c_pos; |
Line 1999 _rl_move_cursor_relative (new, data)
|
Line 2698 _rl_move_cursor_relative (new, data)
|
this case, NEW's display position is not obvious and must be |
this case, NEW's display position is not obvious and must be |
calculated. We need to account for invisible characters in this line, |
calculated. We need to account for invisible characters in this line, |
as long as we are past them and they are counted by _rl_col_width. */ |
as long as we are past them and they are counted by _rl_col_width. */ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
adjust = 1; |
adjust = 1; |
/* Try to short-circuit common cases and eliminate a bunch of multibyte |
/* Try to short-circuit common cases and eliminate a bunch of multibyte |
Line 2024 _rl_move_cursor_relative (new, data)
|
Line 2723 _rl_move_cursor_relative (new, data)
|
if (displaying_prompt_first_line == 0) |
if (displaying_prompt_first_line == 0) |
adjust = 0; |
adjust = 0; |
|
|
|
/* yet another special case: printing the last line of a prompt with |
|
multibyte characters and invisible characters whose printable length |
|
exceeds the screen width with the last invisible character |
|
(prompt_last_invisible) in the last line. IN_INVISLINE is the |
|
offset of DATA in invisible_line */ |
|
in_invisline = 0; |
|
if (data > invisible_line && data < invisible_line+inv_lbreaks[_rl_inv_botlin+1]) |
|
in_invisline = data - invisible_line; |
|
|
/* Use NEW when comparing against the last invisible character in the |
/* Use NEW when comparing against the last invisible character in the |
prompt string, since they're both buffer indices and DPOS is a |
prompt string, since they're both buffer indices and DPOS is a |
desired display position. */ |
desired display position. */ |
|
/* NEW is relative to the current displayed line, while |
|
PROMPT_LAST_INVISIBLE is relative to the entire (wrapped) line. |
|
Need a way to reconcile these two variables by turning NEW into a |
|
buffer position relative to the start of the line */ |
if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */ |
if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */ |
(prompt_physical_chars >= _rl_screenwidth && | (new+in_invisline > prompt_last_invisible) || /* invisible line */ |
| (prompt_physical_chars >= _rl_screenwidth && /* visible line */ |
_rl_last_v_pos == prompt_last_screen_line && |
_rl_last_v_pos == prompt_last_screen_line && |
wrap_offset >= woff && dpos >= woff && |
wrap_offset >= woff && dpos >= woff && |
new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset)))) | new > (prompt_last_invisible-(vis_lbreaks[_rl_last_v_pos])-wrap_offset)))) |
/* XXX last comparison might need to be >= */ |
/* XXX last comparison might need to be >= */ |
{ |
{ |
dpos -= woff; |
dpos -= woff; |
Line 2053 _rl_move_cursor_relative (new, data)
|
Line 2766 _rl_move_cursor_relative (new, data)
|
of moving backwards. */ |
of moving backwards. */ |
/* i == current physical cursor position. */ |
/* i == current physical cursor position. */ |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
i = _rl_last_c_pos; |
i = _rl_last_c_pos; |
else |
else |
#endif |
#endif |
Line 2061 _rl_move_cursor_relative (new, data)
|
Line 2774 _rl_move_cursor_relative (new, data)
|
if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) || |
if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) || |
(_rl_term_autowrap && i == _rl_screenwidth)) |
(_rl_term_autowrap && i == _rl_screenwidth)) |
{ |
{ |
#if defined (__MSDOS__) | _rl_cr (); |
putc ('\r', rl_outstream); | |
#else | |
tputs (_rl_term_cr, 1, _rl_output_character_function); | |
#endif /* !__MSDOS__ */ | |
cpos = _rl_last_c_pos = 0; |
cpos = _rl_last_c_pos = 0; |
} |
} |
|
|
Line 2088 _rl_move_cursor_relative (new, data)
|
Line 2797 _rl_move_cursor_relative (new, data)
|
in the buffer and we have to go back to the beginning of the screen |
in the buffer and we have to go back to the beginning of the screen |
line. In this case, we can use the terminal sequence to move forward |
line. In this case, we can use the terminal sequence to move forward |
if it's available. */ |
if it's available. */ |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | if (mb_cur_max > 1 && rl_byte_oriented == 0) |
{ |
{ |
if (_rl_term_forward_char) |
if (_rl_term_forward_char) |
{ |
{ |
Line 2097 _rl_move_cursor_relative (new, data)
|
Line 2806 _rl_move_cursor_relative (new, data)
|
} |
} |
else |
else |
{ |
{ |
tputs (_rl_term_cr, 1, _rl_output_character_function); | _rl_cr (); |
for (i = 0; i < new; i++) | puts_face (data, dataf, new); |
putc (data[i], rl_outstream); | |
} |
} |
} |
} |
else |
else |
for (i = cpos; i < new; i++) | puts_face (data + cpos, dataf + cpos, new - cpos); |
putc (data[i], rl_outstream); | |
} |
} |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
Line 2121 _rl_move_cursor_relative (new, data)
|
Line 2828 _rl_move_cursor_relative (new, data)
|
|
|
/* PWP: move the cursor up or down. */ |
/* PWP: move the cursor up or down. */ |
void |
void |
_rl_move_vert (to) | _rl_move_vert (int to) |
int to; | |
{ |
{ |
register int delta, i; |
register int delta, i; |
|
|
Line 2133 _rl_move_vert (to)
|
Line 2839 _rl_move_vert (to)
|
{ |
{ |
for (i = 0; i < delta; i++) |
for (i = 0; i < delta; i++) |
putc ('\n', rl_outstream); |
putc ('\n', rl_outstream); |
#if defined (__MSDOS__) | _rl_cr (); |
putc ('\r', rl_outstream); | |
#else | |
tputs (_rl_term_cr, 1, _rl_output_character_function); | |
#endif | |
_rl_last_c_pos = 0; |
_rl_last_c_pos = 0; |
} |
} |
else |
else |
Line 2162 _rl_move_vert (to)
|
Line 2864 _rl_move_vert (to)
|
/* Physically print C on rl_outstream. This is for functions which know |
/* Physically print C on rl_outstream. This is for functions which know |
how to optimize the display. Return the number of characters output. */ |
how to optimize the display. Return the number of characters output. */ |
int |
int |
rl_show_char (c) | rl_show_char (int c) |
int c; | |
{ |
{ |
int n = 1; |
int n = 1; |
if (META_CHAR (c) && (_rl_output_meta_chars == 0)) |
if (META_CHAR (c) && (_rl_output_meta_chars == 0)) |
Line 2190 rl_show_char (c)
|
Line 2891 rl_show_char (c)
|
} |
} |
|
|
int |
int |
rl_character_len (c, pos) | rl_character_len (int c, int pos) |
register int c, pos; | |
{ |
{ |
unsigned char uc; |
unsigned char uc; |
|
|
Line 2246 rl_message (va_alist)
|
Line 2946 rl_message (va_alist)
|
msg_buf = xmalloc (msg_bufsiz = 128); |
msg_buf = xmalloc (msg_bufsiz = 128); |
|
|
#if defined (HAVE_VSNPRINTF) |
#if defined (HAVE_VSNPRINTF) |
bneed = vsnprintf (msg_buf, msg_bufsiz - 1, format, args); | bneed = vsnprintf (msg_buf, msg_bufsiz, format, args); |
if (bneed >= msg_bufsiz - 1) |
if (bneed >= msg_bufsiz - 1) |
{ |
{ |
msg_bufsiz = bneed + 1; |
msg_bufsiz = bneed + 1; |
Line 2279 rl_message (va_alist)
|
Line 2979 rl_message (va_alist)
|
local_prompt = (char *)NULL; |
local_prompt = (char *)NULL; |
} |
} |
rl_display_prompt = msg_buf; |
rl_display_prompt = msg_buf; |
local_prompt = expand_prompt (msg_buf, &prompt_visible_length, | local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length, |
&prompt_last_invisible, | &prompt_last_invisible, |
&prompt_invis_chars_first_line, | &prompt_invis_chars_first_line, |
&prompt_physical_chars); | &prompt_physical_chars); |
local_prompt_prefix = (char *)NULL; |
local_prompt_prefix = (char *)NULL; |
local_prompt_len = local_prompt ? strlen (local_prompt) : 0; |
local_prompt_len = local_prompt ? strlen (local_prompt) : 0; |
(*rl_redisplay_function) (); |
(*rl_redisplay_function) (); |
Line 2312 rl_message (format, arg1, arg2)
|
Line 3012 rl_message (format, arg1, arg2)
|
FREE (local_prompt_prefix); |
FREE (local_prompt_prefix); |
local_prompt = (char *)NULL; |
local_prompt = (char *)NULL; |
} |
} |
local_prompt = expand_prompt (msg_buf, &prompt_visible_length, | local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length, |
&prompt_last_invisible, | &prompt_last_invisible, |
&prompt_invis_chars_first_line, | &prompt_invis_chars_first_line, |
&prompt_physical_chars); | &prompt_physical_chars); |
local_prompt_prefix = (char *)NULL; |
local_prompt_prefix = (char *)NULL; |
local_prompt_len = local_prompt ? strlen (local_prompt) : 0; |
local_prompt_len = local_prompt ? strlen (local_prompt) : 0; |
(*rl_redisplay_function) (); |
(*rl_redisplay_function) (); |
Line 2326 rl_message (format, arg1, arg2)
|
Line 3026 rl_message (format, arg1, arg2)
|
|
|
/* How to clear things from the "echo-area". */ |
/* How to clear things from the "echo-area". */ |
int |
int |
rl_clear_message () | rl_clear_message (void) |
{ |
{ |
rl_display_prompt = rl_prompt; |
rl_display_prompt = rl_prompt; |
if (msg_saved_prompt) |
if (msg_saved_prompt) |
Line 2339 rl_clear_message ()
|
Line 3039 rl_clear_message ()
|
} |
} |
|
|
int |
int |
rl_reset_line_state () | rl_reset_line_state (void) |
{ |
{ |
rl_on_new_line (); |
rl_on_new_line (); |
|
|
Line 2348 rl_reset_line_state ()
|
Line 3048 rl_reset_line_state ()
|
return 0; |
return 0; |
} |
} |
|
|
|
/* Save all of the variables associated with the prompt and its display. Most |
|
of the complexity is dealing with the invisible characters in the prompt |
|
string and where they are. There are enough of these that I should consider |
|
a struct. */ |
void |
void |
rl_save_prompt () | rl_save_prompt (void) |
{ |
{ |
saved_local_prompt = local_prompt; |
saved_local_prompt = local_prompt; |
saved_local_prefix = local_prompt_prefix; |
saved_local_prefix = local_prompt_prefix; |
Line 2359 rl_save_prompt ()
|
Line 3063 rl_save_prompt ()
|
saved_visible_length = prompt_visible_length; |
saved_visible_length = prompt_visible_length; |
saved_invis_chars_first_line = prompt_invis_chars_first_line; |
saved_invis_chars_first_line = prompt_invis_chars_first_line; |
saved_physical_chars = prompt_physical_chars; |
saved_physical_chars = prompt_physical_chars; |
|
saved_local_prompt_newlines = local_prompt_newlines; |
|
|
local_prompt = local_prompt_prefix = (char *)0; |
local_prompt = local_prompt_prefix = (char *)0; |
local_prompt_len = 0; |
local_prompt_len = 0; |
|
local_prompt_newlines = (int *)0; |
|
|
prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; |
prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; |
prompt_invis_chars_first_line = prompt_physical_chars = 0; |
prompt_invis_chars_first_line = prompt_physical_chars = 0; |
} |
} |
|
|
void |
void |
rl_restore_prompt () | rl_restore_prompt (void) |
{ |
{ |
FREE (local_prompt); |
FREE (local_prompt); |
FREE (local_prompt_prefix); |
FREE (local_prompt_prefix); |
|
FREE (local_prompt_newlines); |
|
|
local_prompt = saved_local_prompt; |
local_prompt = saved_local_prompt; |
local_prompt_prefix = saved_local_prefix; |
local_prompt_prefix = saved_local_prefix; |
local_prompt_len = saved_local_length; |
local_prompt_len = saved_local_length; |
|
local_prompt_newlines = saved_local_prompt_newlines; |
|
|
prompt_prefix_length = saved_prefix_length; |
prompt_prefix_length = saved_prefix_length; |
prompt_last_invisible = saved_last_invisible; |
prompt_last_invisible = saved_last_invisible; |
prompt_visible_length = saved_visible_length; |
prompt_visible_length = saved_visible_length; |
Line 2386 rl_restore_prompt ()
|
Line 3096 rl_restore_prompt ()
|
saved_local_length = 0; |
saved_local_length = 0; |
saved_last_invisible = saved_visible_length = saved_prefix_length = 0; |
saved_last_invisible = saved_visible_length = saved_prefix_length = 0; |
saved_invis_chars_first_line = saved_physical_chars = 0; |
saved_invis_chars_first_line = saved_physical_chars = 0; |
|
saved_local_prompt_newlines = 0; |
} |
} |
|
|
char * |
char * |
_rl_make_prompt_for_search (pchar) | _rl_make_prompt_for_search (int pchar) |
int pchar; | |
{ |
{ |
int len; |
int len; |
char *pmt, *p; |
char *pmt, *p; |
Line 2428 _rl_make_prompt_for_search (pchar)
|
Line 3138 _rl_make_prompt_for_search (pchar)
|
|
|
/* Quick redisplay hack when erasing characters at the end of the line. */ |
/* Quick redisplay hack when erasing characters at the end of the line. */ |
void |
void |
_rl_erase_at_end_of_line (l) | _rl_erase_at_end_of_line (int l) |
int l; | |
{ |
{ |
register int i; |
register int i; |
|
|
Line 2443 _rl_erase_at_end_of_line (l)
|
Line 3152 _rl_erase_at_end_of_line (l)
|
} |
} |
|
|
/* Clear to the end of the line. COUNT is the minimum |
/* Clear to the end of the line. COUNT is the minimum |
number of character spaces to clear, */ | number of character spaces to clear, but we use a terminal escape |
| sequence if available. */ |
void |
void |
_rl_clear_to_eol (count) | _rl_clear_to_eol (int count) |
int count; | |
{ |
{ |
#ifndef __MSDOS__ |
#ifndef __MSDOS__ |
if (_rl_term_clreol) |
if (_rl_term_clreol) |
Line 2460 _rl_clear_to_eol (count)
|
Line 3169 _rl_clear_to_eol (count)
|
/* Clear to the end of the line using spaces. COUNT is the minimum |
/* Clear to the end of the line using spaces. COUNT is the minimum |
number of character spaces to clear, */ |
number of character spaces to clear, */ |
static void |
static void |
space_to_eol (count) | space_to_eol (int count) |
int count; | |
{ |
{ |
register int i; |
register int i; |
|
|
for (i = 0; i < count; i++) |
for (i = 0; i < count; i++) |
putc (' ', rl_outstream); | putc (' ', rl_outstream); |
|
|
_rl_last_c_pos += count; |
_rl_last_c_pos += count; |
} |
} |
|
|
void |
void |
_rl_clear_screen () | _rl_clear_screen (int clrscr) |
{ |
{ |
#ifndef __DJGPP__ | #if defined (__DJGPP__) |
| ScreenClear (); |
| ScreenSetCursor (0, 0); |
| #else |
if (_rl_term_clrpag) |
if (_rl_term_clrpag) |
tputs (_rl_term_clrpag, 1, _rl_output_character_function); | { |
| tputs (_rl_term_clrpag, 1, _rl_output_character_function); |
| if (clrscr && _rl_term_clrscroll) |
| tputs (_rl_term_clrscroll, 1, _rl_output_character_function); |
| } |
else |
else |
rl_crlf (); |
rl_crlf (); |
#else |
|
ScreenClear (); |
|
ScreenSetCursor (0, 0); |
|
#endif /* __DJGPP__ */ |
#endif /* __DJGPP__ */ |
} |
} |
|
|
/* Insert COUNT characters from STRING to the output stream at column COL. */ |
/* Insert COUNT characters from STRING to the output stream at column COL. */ |
static void |
static void |
insert_some_chars (string, count, col) | insert_some_chars (char *string, int count, int col) |
char *string; | |
int count, col; | |
{ |
{ |
open_some_spaces (col); |
open_some_spaces (col); |
_rl_output_some_chars (string, count); |
_rl_output_some_chars (string, count); |
Line 2499 insert_some_chars (string, count, col)
|
Line 3209 insert_some_chars (string, count, col)
|
ncurses documentation and use either im/ei with explicit spaces, or IC/ic |
ncurses documentation and use either im/ei with explicit spaces, or IC/ic |
by itself. We assume there will either be ei or we don't need to use it. */ |
by itself. We assume there will either be ei or we don't need to use it. */ |
static void |
static void |
open_some_spaces (col) | open_some_spaces (int col) |
int col; | |
{ |
{ |
#if !defined (__MSDOS__) && !defined (__MINGW32__) | #if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION)) |
char *buffer; |
char *buffer; |
register int i; |
register int i; |
|
|
Line 2531 open_some_spaces (col)
|
Line 3240 open_some_spaces (col)
|
for (i = col; i--; ) |
for (i = col; i--; ) |
tputs (_rl_term_ic, 1, _rl_output_character_function); |
tputs (_rl_term_ic, 1, _rl_output_character_function); |
} |
} |
#endif /* !__MSDOS__ && !__MINGW32__ */ | #endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/ |
} |
} |
|
|
/* Delete COUNT characters from the display line. */ |
/* Delete COUNT characters from the display line. */ |
static void |
static void |
delete_chars (count) | delete_chars (int count) |
int count; | |
{ |
{ |
if (count > _rl_screenwidth) /* XXX */ |
if (count > _rl_screenwidth) /* XXX */ |
return; |
return; |
|
|
#if !defined (__MSDOS__) && !defined (__MINGW32__) | #if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION)) |
if (_rl_term_DC && *_rl_term_DC) |
if (_rl_term_DC && *_rl_term_DC) |
{ |
{ |
char *buffer; |
char *buffer; |
Line 2555 delete_chars (count)
|
Line 3263 delete_chars (count)
|
while (count--) |
while (count--) |
tputs (_rl_term_dc, 1, _rl_output_character_function); |
tputs (_rl_term_dc, 1, _rl_output_character_function); |
} |
} |
#endif /* !__MSDOS__ && !__MINGW32__ */ | #endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/ |
} |
} |
|
|
void |
void |
_rl_update_final () | _rl_update_final (void) |
{ |
{ |
int full_lines; | int full_lines, woff, botline_length; |
|
|
|
if (line_structures_initialized == 0) |
|
return; |
|
|
full_lines = 0; |
full_lines = 0; |
/* If the cursor is the only thing on an otherwise-blank last line, |
/* If the cursor is the only thing on an otherwise-blank last line, |
compensate so we don't print an extra CRLF. */ |
compensate so we don't print an extra CRLF. */ |
Line 2573 _rl_update_final ()
|
Line 3284 _rl_update_final ()
|
full_lines = 1; |
full_lines = 1; |
} |
} |
_rl_move_vert (_rl_vis_botlin); |
_rl_move_vert (_rl_vis_botlin); |
|
woff = W_OFFSET(_rl_vis_botlin, wrap_offset); |
|
botline_length = VIS_LLEN(_rl_vis_botlin) - woff; |
/* If we've wrapped lines, remove the final xterm line-wrap flag. */ |
/* If we've wrapped lines, remove the final xterm line-wrap flag. */ |
if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth)) | if (full_lines && _rl_term_autowrap && botline_length == _rl_screenwidth) |
{ |
{ |
char *last_line; | char *last_line, *last_face; |
|
|
last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; | /* LAST_LINE includes invisible characters, so if you want to get the |
| last character of the first line, you have to take WOFF into account. |
| This needs to be done for both calls to _rl_move_cursor_relative, |
| which takes a buffer position as the first argument, and any direct |
| subscripts of LAST_LINE. */ |
| last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; /* = VIS_CHARS(_rl_vis_botlin); */ |
| last_face = &vis_face[vis_lbreaks[_rl_vis_botlin]]; /* = VIS_CHARS(_rl_vis_botlin); */ |
cpos_buffer_position = -1; /* don't know where we are in buffer */ |
cpos_buffer_position = -1; /* don't know where we are in buffer */ |
_rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */ | _rl_move_cursor_relative (_rl_screenwidth - 1 + woff, last_line, last_face); /* XXX */ |
_rl_clear_to_eol (0); |
_rl_clear_to_eol (0); |
putc (last_line[_rl_screenwidth - 1], rl_outstream); | puts_face (&last_line[_rl_screenwidth - 1 + woff], |
| &last_face[_rl_screenwidth - 1 + woff], 1); |
} |
} |
_rl_vis_botlin = 0; |
_rl_vis_botlin = 0; |
rl_crlf (); | if (botline_length > 0 || _rl_last_c_pos > 0) |
| rl_crlf (); |
fflush (rl_outstream); |
fflush (rl_outstream); |
rl_display_fixed++; |
rl_display_fixed++; |
} |
} |
|
|
/* Move to the start of the current line. */ |
/* Move to the start of the current line. */ |
static void |
static void |
cr () | cr (void) |
{ |
{ |
if (_rl_term_cr) | _rl_cr (); |
{ | _rl_last_c_pos = 0; |
#if defined (__MSDOS__) | |
putc ('\r', rl_outstream); | |
#else | |
tputs (_rl_term_cr, 1, _rl_output_character_function); | |
#endif | |
_rl_last_c_pos = 0; | |
} | |
} |
} |
|
|
/* Redraw the last line of a multi-line prompt that may possibly contain |
/* Redraw the last line of a multi-line prompt that may possibly contain |
terminal escape sequences. Called with the cursor at column 0 of the |
terminal escape sequences. Called with the cursor at column 0 of the |
line to draw the prompt on. */ |
line to draw the prompt on. */ |
static void |
static void |
redraw_prompt (t) | redraw_prompt (char *t) |
char *t; | |
{ |
{ |
char *oldp; |
char *oldp; |
|
|
Line 2618 redraw_prompt (t)
|
Line 3331 redraw_prompt (t)
|
rl_save_prompt (); |
rl_save_prompt (); |
|
|
rl_display_prompt = t; |
rl_display_prompt = t; |
local_prompt = expand_prompt (t, &prompt_visible_length, | local_prompt = expand_prompt (t, PMT_MULTILINE, |
| &prompt_visible_length, |
&prompt_last_invisible, |
&prompt_last_invisible, |
&prompt_invis_chars_first_line, |
&prompt_invis_chars_first_line, |
&prompt_physical_chars); |
&prompt_physical_chars); |
Line 2633 redraw_prompt (t)
|
Line 3347 redraw_prompt (t)
|
|
|
/* Redisplay the current line after a SIGWINCH is received. */ |
/* Redisplay the current line after a SIGWINCH is received. */ |
void |
void |
_rl_redisplay_after_sigwinch () | _rl_redisplay_after_sigwinch (void) |
{ |
{ |
char *t; |
char *t; |
|
|
Line 2645 _rl_redisplay_after_sigwinch ()
|
Line 3359 _rl_redisplay_after_sigwinch ()
|
{ |
{ |
_rl_move_vert (_rl_vis_botlin); |
_rl_move_vert (_rl_vis_botlin); |
|
|
#if defined (__MSDOS__) | _rl_cr (); |
putc ('\r', rl_outstream); | |
#else | |
tputs (_rl_term_cr, 1, _rl_output_character_function); | |
#endif | |
_rl_last_c_pos = 0; |
_rl_last_c_pos = 0; |
#if defined (__MSDOS__) | |
space_to_eol (_rl_screenwidth); | #if !defined (__MSDOS__) |
putc ('\r', rl_outstream); | |
#else | |
if (_rl_term_clreol) |
if (_rl_term_clreol) |
tputs (_rl_term_clreol, 1, _rl_output_character_function); |
tputs (_rl_term_clreol, 1, _rl_output_character_function); |
else |
else |
|
#endif |
{ |
{ |
space_to_eol (_rl_screenwidth); |
space_to_eol (_rl_screenwidth); |
tputs (_rl_term_cr, 1, _rl_output_character_function); | _rl_cr (); |
} |
} |
#endif | |
if (_rl_last_v_pos > 0) |
if (_rl_last_v_pos > 0) |
_rl_move_vert (0); |
_rl_move_vert (0); |
} |
} |
Line 2678 _rl_redisplay_after_sigwinch ()
|
Line 3387 _rl_redisplay_after_sigwinch ()
|
} |
} |
|
|
void |
void |
_rl_clean_up_for_exit () | _rl_clean_up_for_exit (void) |
{ |
{ |
if (_rl_echoing_p) |
if (_rl_echoing_p) |
{ |
{ |
Line 2691 _rl_clean_up_for_exit ()
|
Line 3400 _rl_clean_up_for_exit ()
|
} |
} |
|
|
void |
void |
_rl_erase_entire_line () | _rl_erase_entire_line (void) |
{ |
{ |
cr (); |
cr (); |
_rl_clear_to_eol (0); |
_rl_clear_to_eol (0); |
Line 2699 _rl_erase_entire_line ()
|
Line 3408 _rl_erase_entire_line ()
|
fflush (rl_outstream); |
fflush (rl_outstream); |
} |
} |
|
|
|
void |
|
_rl_ttyflush (void) |
|
{ |
|
fflush (rl_outstream); |
|
} |
|
|
/* return the `current display line' of the cursor -- the number of lines to |
/* return the `current display line' of the cursor -- the number of lines to |
move up to get to the first screen line of the current readline line. */ |
move up to get to the first screen line of the current readline line. */ |
int |
int |
_rl_current_display_line () | _rl_current_display_line (void) |
{ |
{ |
int ret, nleft; |
int ret, nleft; |
|
|
Line 2721 _rl_current_display_line ()
|
Line 3436 _rl_current_display_line ()
|
return ret; |
return ret; |
} |
} |
|
|
|
void |
|
_rl_refresh_line (void) |
|
{ |
|
rl_clear_visible_line (); |
|
rl_redraw_prompt_last_line (); |
|
rl_keep_mark_active (); |
|
} |
|
|
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
/* Calculate the number of screen columns occupied by STR from START to END. |
/* Calculate the number of screen columns occupied by STR from START to END. |
In the case of multibyte characters with stateful encoding, we have to |
In the case of multibyte characters with stateful encoding, we have to |
scan from the beginning of the string to take the state into account. */ |
scan from the beginning of the string to take the state into account. */ |
static int |
static int |
_rl_col_width (str, start, end, flags) | _rl_col_width (const char *str, int start, int end, int flags) |
const char *str; | |
int start, end, flags; | |
{ |
{ |
wchar_t wc; |
wchar_t wc; |
mbstate_t ps; |
mbstate_t ps; |
Line 2761 _rl_col_width (str, start, end, flags)
|
Line 3482 _rl_col_width (str, start, end, flags)
|
|
|
while (point < start) |
while (point < start) |
{ |
{ |
tmp = mbrlen (str + point, max, &ps); | if (_rl_utf8locale && UTF8_SINGLEBYTE(str[point])) |
| { |
| memset (&ps, 0, sizeof (mbstate_t)); |
| tmp = 1; |
| } |
| else |
| tmp = mbrlen (str + point, max, &ps); |
if (MB_INVALIDCH ((size_t)tmp)) |
if (MB_INVALIDCH ((size_t)tmp)) |
{ |
{ |
/* In this case, the bytes are invalid or too short to compose a |
/* In this case, the bytes are invalid or too short to compose a |
Line 2790 _rl_col_width (str, start, end, flags)
|
Line 3517 _rl_col_width (str, start, end, flags)
|
|
|
while (point < end) |
while (point < end) |
{ |
{ |
tmp = mbrtowc (&wc, str + point, max, &ps); | if (_rl_utf8locale && UTF8_SINGLEBYTE(str[point])) |
| { |
| tmp = 1; |
| wc = (wchar_t) str[point]; |
| } |
| else |
| tmp = mbrtowc (&wc, str + point, max, &ps); |
if (MB_INVALIDCH ((size_t)tmp)) |
if (MB_INVALIDCH ((size_t)tmp)) |
{ |
{ |
/* In this case, the bytes are invalid or too short to compose a |
/* In this case, the bytes are invalid or too short to compose a |