version 1.133, 2016/05/13 15:55:59 |
version 1.141, 2017/04/21 05:38:03 |
Line 95 int rl_catch_sigwinch = 1; |
|
Line 95 int rl_catch_sigwinch = 1; |
|
|
|
int history_base = 1; /* probably never subject to change */ |
int history_base = 1; /* probably never subject to change */ |
int history_length = 0; |
int history_length = 0; |
|
int history_offset = 0; |
int max_input_history = 0; |
int max_input_history = 0; |
char history_expansion_char = '!'; |
char history_expansion_char = '!'; |
char history_subst_char = '^'; |
char history_subst_char = '^'; |
Line 156 char *rl_special_prefixes = NULL; |
|
Line 157 char *rl_special_prefixes = NULL; |
|
*/ |
*/ |
int rl_completion_append_character = ' '; |
int rl_completion_append_character = ' '; |
|
|
/* |
|
* When the history cursor is on the newest element and next_history() |
|
* is called, GNU readline moves the cursor beyond the newest element. |
|
* The editline library does not provide data structures to express |
|
* that state, so we need a local flag. |
|
*/ |
|
static int current_history_valid = 1; |
|
|
|
/* stuff below is used internally by libedit for readline emulation */ |
/* stuff below is used internally by libedit for readline emulation */ |
|
|
static History *h = NULL; |
static History *h = NULL; |
Line 176 static unsigned char _el_rl_complete(Ed |
|
Line 169 static unsigned char _el_rl_complete(Ed |
|
static unsigned char _el_rl_tstp(EditLine *, int); |
static unsigned char _el_rl_tstp(EditLine *, int); |
static char *_get_prompt(EditLine *); |
static char *_get_prompt(EditLine *); |
static int _getc_function(EditLine *, wchar_t *); |
static int _getc_function(EditLine *, wchar_t *); |
static HIST_ENTRY *_move_history(int); |
|
static int _history_expand_command(const char *, size_t, size_t, |
static int _history_expand_command(const char *, size_t, size_t, |
char **); |
char **); |
static char *_rl_compat_sub(const char *, const char *, |
static char *_rl_compat_sub(const char *, const char *, |
Line 184 static char *_rl_compat_sub(const char |
|
Line 176 static char *_rl_compat_sub(const char |
|
static int _rl_event_read_char(EditLine *, wchar_t *); |
static int _rl_event_read_char(EditLine *, wchar_t *); |
static void _rl_update_pos(void); |
static void _rl_update_pos(void); |
|
|
|
static HIST_ENTRY rl_he; |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
static char * |
static char * |
Line 195 _get_prompt(EditLine *el __attribute__(( |
|
Line 188 _get_prompt(EditLine *el __attribute__(( |
|
|
|
|
|
/* |
/* |
* generic function for moving around history |
|
*/ |
|
static HIST_ENTRY * |
|
_move_history(int op) |
|
{ |
|
HistEvent ev; |
|
static HIST_ENTRY rl_he; |
|
|
|
if (history(h, &ev, op) != 0) |
|
return NULL; |
|
|
|
rl_he.line = ev.str; |
|
rl_he.data = NULL; |
|
|
|
return &rl_he; |
|
} |
|
|
|
|
|
/* |
|
* read one key from user defined input function |
* read one key from user defined input function |
*/ |
*/ |
static int |
static int |
Line 222 _getc_function(EditLine *el __attribute_ |
|
Line 196 _getc_function(EditLine *el __attribute_ |
|
{ |
{ |
int i; |
int i; |
|
|
i = (*rl_getc_function)(NULL); |
i = (*rl_getc_function)(rl_instream); |
if (i == -1) |
if (i == -1) |
return 0; |
return 0; |
*c = (wchar_t)i; |
*c = (wchar_t)i; |
Line 299 rl_initialize(void) |
|
Line 273 rl_initialize(void) |
|
int editmode = 1; |
int editmode = 1; |
struct termios t; |
struct termios t; |
|
|
current_history_valid = 1; |
|
|
|
if (e != NULL) |
if (e != NULL) |
el_end(e); |
el_end(e); |
if (h != NULL) |
if (h != NULL) |
Line 494 using_history(void) |
|
Line 466 using_history(void) |
|
{ |
{ |
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
|
history_offset = history_length; |
} |
} |
|
|
|
|
Line 575 get_history_event(const char *cmd, int * |
|
Line 548 get_history_event(const char *cmd, int * |
|
} |
} |
|
|
if ('0' <= cmd[idx] && cmd[idx] <= '9') { |
if ('0' <= cmd[idx] && cmd[idx] <= '9') { |
HIST_ENTRY *rl_he; |
HIST_ENTRY *he; |
|
|
num = 0; |
num = 0; |
while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') { |
while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') { |
Line 583 get_history_event(const char *cmd, int * |
|
Line 556 get_history_event(const char *cmd, int * |
|
idx++; |
idx++; |
} |
} |
if (sign) |
if (sign) |
num = history_length - num + 1; |
num = history_length - num + history_base; |
|
|
if (!(rl_he = history_get(num))) |
if (!(he = history_get(num))) |
return NULL; |
return NULL; |
|
|
*cindex = idx; |
*cindex = idx; |
return rl_he->line; |
return he->line; |
} |
} |
sub = 0; |
sub = 0; |
if (cmd[idx] == '?') { |
if (cmd[idx] == '?') { |
Line 1179 stifle_history(int max) |
|
Line 1152 stifle_history(int max) |
|
{ |
{ |
HistEvent ev; |
HistEvent ev; |
HIST_ENTRY *he; |
HIST_ENTRY *he; |
int i, len; |
|
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
|
|
len = history_length; |
|
if (history(h, &ev, H_SETSIZE, max) == 0) { |
if (history(h, &ev, H_SETSIZE, max) == 0) { |
max_input_history = max; |
max_input_history = max; |
if (max < len) |
if (history_length > max) |
history_base += len - max; |
history_base = history_length - max; |
for (i = 0; i < len - max; i++) { |
while (history_length > max) { |
he = remove_history(i); |
he = remove_history(0); |
el_free(he->data); |
el_free(he->data); |
el_free((void *)(unsigned long)he->line); |
el_free((void *)(unsigned long)he->line); |
el_free(he); |
el_free(he); |
Line 1452 add_history(const char *line) |
|
Line 1423 add_history(const char *line) |
|
{ |
{ |
HistEvent ev; |
HistEvent ev; |
|
|
if (line == NULL) |
|
return 0; |
|
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
|
|
(void)history(h, &ev, H_ENTER, line); |
if (history(h, &ev, H_ENTER, line) == -1) |
if (history(h, &ev, H_GETSIZE) == 0) |
return 0; |
history_length = ev.num; |
|
current_history_valid = 1; |
|
|
|
return !(history_length > 0); /* return 0 if all is okay */ |
(void)history(h, &ev, H_GETSIZE); |
|
if (ev.num == history_length) |
|
history_base++; |
|
else |
|
history_length = ev.num; |
|
return 0; |
} |
} |
|
|
|
|
Line 1553 clear_history(void) |
|
Line 1524 clear_history(void) |
|
rl_initialize(); |
rl_initialize(); |
|
|
(void)history(h, &ev, H_CLEAR); |
(void)history(h, &ev, H_CLEAR); |
history_length = 0; |
history_offset = history_length = 0; |
current_history_valid = 1; |
|
} |
} |
|
|
|
|
Line 1564 clear_history(void) |
|
Line 1534 clear_history(void) |
|
int |
int |
where_history(void) |
where_history(void) |
{ |
{ |
HistEvent ev; |
return history_offset; |
int curr_num, off; |
} |
|
|
if (history(h, &ev, H_CURR) != 0) |
static HIST_ENTRY **_history_listp; |
return 0; |
static HIST_ENTRY *_history_list; |
curr_num = ev.num; |
|
|
|
/* start from the oldest */ |
HIST_ENTRY ** |
(void)history(h, &ev, H_LAST); |
history_list(void) |
|
{ |
|
HistEvent ev; |
|
HIST_ENTRY **nlp, *nl; |
|
int i; |
|
|
/* position is zero-based */ |
if (history(h, &ev, H_LAST) != 0) |
off = 0; |
return NULL; |
while (ev.num != curr_num && history(h, &ev, H_PREV) == 0) |
|
off++; |
|
|
|
return off; |
if ((nlp = el_realloc(_history_listp, |
} |
(size_t)history_length * sizeof(*nlp))) == NULL) |
|
return NULL; |
|
_history_listp = nlp; |
|
|
|
if ((nl = el_realloc(_history_list, |
|
(size_t)history_length * sizeof(*nl))) == NULL) |
|
return NULL; |
|
_history_list = nl; |
|
|
|
i = 0; |
|
do { |
|
_history_listp[i] = &_history_list[i]; |
|
_history_list[i].line = ev.str; |
|
_history_list[i].data = NULL; |
|
if (i++ == history_length) |
|
abort(); |
|
} while (history(h, &ev, H_PREV) == 0); |
|
return _history_listp; |
|
} |
|
|
/* |
/* |
* returns current history event or NULL if there is no such event |
* returns current history event or NULL if there is no such event |
Line 1589 where_history(void) |
|
Line 1577 where_history(void) |
|
HIST_ENTRY * |
HIST_ENTRY * |
current_history(void) |
current_history(void) |
{ |
{ |
|
HistEvent ev; |
|
|
|
if (history(h, &ev, H_PREV_EVENT, history_offset + 1) != 0) |
|
return NULL; |
|
|
return current_history_valid ? _move_history(H_CURR) : NULL; |
rl_he.line = ev.str; |
|
rl_he.data = NULL; |
|
return &rl_he; |
} |
} |
|
|
|
|
Line 1627 history_total_bytes(void) |
|
Line 1621 history_total_bytes(void) |
|
int |
int |
history_set_pos(int pos) |
history_set_pos(int pos) |
{ |
{ |
HistEvent ev; |
|
int curr_num; |
|
|
|
if (pos >= history_length || pos < 0) |
if (pos >= history_length || pos < 0) |
return 0; |
return 0; |
|
|
(void)history(h, &ev, H_CURR); |
history_offset = pos; |
curr_num = ev.num; |
|
current_history_valid = 1; |
|
|
|
/* |
|
* use H_DELDATA to set to nth history (without delete) by passing |
|
* (void **)-1 |
|
*/ |
|
if (history(h, &ev, H_DELDATA, pos, (void **)-1)) { |
|
(void)history(h, &ev, H_SET, curr_num); |
|
return 0; |
|
} |
|
return 1; |
return 1; |
} |
} |
|
|
Line 1656 history_set_pos(int pos) |
|
Line 1636 history_set_pos(int pos) |
|
HIST_ENTRY * |
HIST_ENTRY * |
previous_history(void) |
previous_history(void) |
{ |
{ |
|
HistEvent ev; |
|
|
if (current_history_valid == 0) { |
if (history_offset == 0) |
current_history_valid = 1; |
return NULL; |
return _move_history(H_CURR); |
|
} |
if (history(h, &ev, H_LAST) != 0) |
return _move_history(H_NEXT); |
return NULL; |
|
|
|
history_offset--; |
|
return current_history(); |
} |
} |
|
|
|
|
Line 1671 previous_history(void) |
|
Line 1655 previous_history(void) |
|
HIST_ENTRY * |
HIST_ENTRY * |
next_history(void) |
next_history(void) |
{ |
{ |
HIST_ENTRY *he; |
HistEvent ev; |
|
|
he = _move_history(H_PREV); |
if (history_offset >= history_length) |
if (he == NULL) |
return NULL; |
current_history_valid = 0; |
|
return he; |
if (history(h, &ev, H_LAST) != 0) |
|
return NULL; |
|
|
|
history_offset++; |
|
return current_history(); |
} |
} |
|
|
|
|
Line 1824 _el_rl_tstp(EditLine *el __attribute__(( |
|
Line 1812 _el_rl_tstp(EditLine *el __attribute__(( |
|
return CC_NORM; |
return CC_NORM; |
} |
} |
|
|
/* |
|
* Display list of strings in columnar format on readline's output stream. |
|
* 'matches' is list of strings, 'len' is number of strings in 'matches', |
|
* 'max' is maximum length of string in 'matches'. |
|
*/ |
|
void |
|
rl_display_match_list(char **matches, int len, int max) |
|
{ |
|
|
|
fn_display_match_list(e, matches, (size_t)len, (size_t)max); |
|
} |
|
|
|
static const char * |
static const char * |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
_rl_completion_append_character_function(const char *dummy |
_rl_completion_append_character_function(const char *dummy |
Line 1849 _rl_completion_append_character_function |
|
Line 1825 _rl_completion_append_character_function |
|
|
|
|
|
/* |
/* |
|
* Display list of strings in columnar format on readline's output stream. |
|
* 'matches' is list of strings, 'len' is number of strings in 'matches', |
|
* 'max' is maximum length of string in 'matches'. |
|
*/ |
|
void |
|
rl_display_match_list(char **matches, int len, int max) |
|
{ |
|
|
|
fn_display_match_list(e, matches, (size_t)len, (size_t)max, |
|
_rl_completion_append_character_function); |
|
} |
|
|
|
/* |
* complete word at current point |
* complete word at current point |
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |