Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/less/cmdbuf.c
Show All 26 Lines | |||||
static int cmd_col; /* Current column of the cursor */ | static int cmd_col; /* Current column of the cursor */ | ||||
static int prompt_col; /* Column of cursor just after prompt */ | static int prompt_col; /* Column of cursor just after prompt */ | ||||
static char *cp; /* Pointer into cmdbuf */ | static char *cp; /* Pointer into cmdbuf */ | ||||
static int cmd_offset; /* Index into cmdbuf of first displayed char */ | static int cmd_offset; /* Index into cmdbuf of first displayed char */ | ||||
static int literal; /* Next input char should not be interpreted */ | static int literal; /* Next input char should not be interpreted */ | ||||
static int updown_match = -1; /* Prefix length in up/down movement */ | static int updown_match = -1; /* Prefix length in up/down movement */ | ||||
#if TAB_COMPLETE_FILENAME | #if TAB_COMPLETE_FILENAME | ||||
static int cmd_complete(); | static int cmd_complete(int action); | ||||
/* | /* | ||||
* These variables are statics used by cmd_complete. | * These variables are statics used by cmd_complete. | ||||
*/ | */ | ||||
static int in_completion = 0; | static int in_completion = 0; | ||||
static char *tk_text; | static char *tk_text; | ||||
static char *tk_original; | static char *tk_original; | ||||
static char *tk_ipoint; | static char *tk_ipoint; | ||||
static char *tk_trial; | static char *tk_trial; | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
static int cmd_mbc_buf_len; | static int cmd_mbc_buf_len; | ||||
static int cmd_mbc_buf_index; | static int cmd_mbc_buf_index; | ||||
/* | /* | ||||
* Reset command buffer (to empty). | * Reset command buffer (to empty). | ||||
*/ | */ | ||||
public void | public void | ||||
cmd_reset() | cmd_reset(void) | ||||
{ | { | ||||
cp = cmdbuf; | cp = cmdbuf; | ||||
*cp = '\0'; | *cp = '\0'; | ||||
cmd_col = 0; | cmd_col = 0; | ||||
cmd_offset = 0; | cmd_offset = 0; | ||||
literal = 0; | literal = 0; | ||||
cmd_mbc_buf_len = 0; | cmd_mbc_buf_len = 0; | ||||
updown_match = -1; | updown_match = -1; | ||||
} | } | ||||
/* | /* | ||||
* Clear command line. | * Clear command line. | ||||
*/ | */ | ||||
public void | public void | ||||
clear_cmd() | clear_cmd(void) | ||||
{ | { | ||||
cmd_col = prompt_col = 0; | cmd_col = prompt_col = 0; | ||||
cmd_mbc_buf_len = 0; | cmd_mbc_buf_len = 0; | ||||
updown_match = -1; | updown_match = -1; | ||||
} | } | ||||
/* | /* | ||||
* Display a string, usually as a prompt for input into the command buffer. | * Display a string, usually as a prompt for input into the command buffer. | ||||
*/ | */ | ||||
public void | public void | ||||
cmd_putstr(s) | cmd_putstr(constant char *s) | ||||
char *s; | |||||
{ | { | ||||
LWCHAR prev_ch = 0; | LWCHAR prev_ch = 0; | ||||
LWCHAR ch; | LWCHAR ch; | ||||
char *endline = s + strlen(s); | constant char *endline = s + strlen(s); | ||||
while (*s != '\0') | while (*s != '\0') | ||||
{ | { | ||||
char *ns = s; | constant char *ns = s; | ||||
ch = step_char(&ns, +1, endline); | ch = step_char(&ns, +1, endline); | ||||
while (s < ns) | while (s < ns) | ||||
putchr(*s++); | putchr(*s++); | ||||
if (!utf_mode) | if (!utf_mode) | ||||
{ | { | ||||
cmd_col++; | cmd_col++; | ||||
prompt_col++; | prompt_col++; | ||||
} else if (!is_composing_char(ch) && | } else if (!is_composing_char(ch) && | ||||
!is_combining_char(prev_ch, ch)) | !is_combining_char(prev_ch, ch)) | ||||
{ | { | ||||
int width = is_wide_char(ch) ? 2 : 1; | int width = is_wide_char(ch) ? 2 : 1; | ||||
cmd_col += width; | cmd_col += width; | ||||
prompt_col += width; | prompt_col += width; | ||||
} | } | ||||
prev_ch = ch; | prev_ch = ch; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* How many characters are in the command buffer? | * How many characters are in the command buffer? | ||||
*/ | */ | ||||
public int | public int | ||||
len_cmdbuf() | len_cmdbuf(void) | ||||
{ | { | ||||
char *s = cmdbuf; | constant char *s = cmdbuf; | ||||
char *endline = s + strlen(s); | constant char *endline = s + strlen(s); | ||||
int len = 0; | int len = 0; | ||||
while (*s != '\0') | while (*s != '\0') | ||||
{ | { | ||||
step_char(&s, +1, endline); | step_char(&s, +1, endline); | ||||
len++; | len++; | ||||
} | } | ||||
return (len); | return (len); | ||||
} | } | ||||
/* | /* | ||||
* Common part of cmd_step_right() and cmd_step_left(). | * Common part of cmd_step_right() and cmd_step_left(). | ||||
*/ | */ | ||||
static char * | static char * | ||||
cmd_step_common(p, ch, len, pwidth, bswidth) | cmd_step_common(constant char *p, LWCHAR ch, int len, int *pwidth, int *bswidth) | ||||
char *p; | |||||
LWCHAR ch; | |||||
int len; | |||||
int *pwidth; | |||||
int *bswidth; | |||||
{ | { | ||||
char *pr; | char *pr; | ||||
if (len == 1) | if (len == 1) | ||||
{ | { | ||||
pr = prchar((int) ch); | pr = prchar((int) ch); | ||||
if (pwidth != NULL || bswidth != NULL) | if (pwidth != NULL || bswidth != NULL) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | cmd_step_common(constant char *p, LWCHAR ch, int len, int *pwidth, int *bswidth) | ||||
return (pr); | return (pr); | ||||
} | } | ||||
/* | /* | ||||
* Step a pointer one character right in the command buffer. | * Step a pointer one character right in the command buffer. | ||||
*/ | */ | ||||
static char * | static char * | ||||
cmd_step_right(pp, pwidth, bswidth) | cmd_step_right(char **pp, int *pwidth, int *bswidth) | ||||
char **pp; | |||||
int *pwidth; | |||||
int *bswidth; | |||||
{ | { | ||||
char *p = *pp; | char *p = *pp; | ||||
LWCHAR ch = step_char(pp, +1, p + strlen(p)); | LWCHAR ch = step_char((constant char **)pp, +1, p + strlen(p)); | ||||
return cmd_step_common(p, ch, *pp - p, pwidth, bswidth); | return cmd_step_common(p, ch, *pp - p, pwidth, bswidth); | ||||
} | } | ||||
/* | /* | ||||
* Step a pointer one character left in the command buffer. | * Step a pointer one character left in the command buffer. | ||||
*/ | */ | ||||
static char * | static char * | ||||
cmd_step_left(pp, pwidth, bswidth) | cmd_step_left(char **pp, int *pwidth, int *bswidth) | ||||
char **pp; | |||||
int *pwidth; | |||||
int *bswidth; | |||||
{ | { | ||||
char *p = *pp; | char *p = *pp; | ||||
LWCHAR ch = step_char(pp, -1, cmdbuf); | LWCHAR ch = step_char((constant char **)pp, -1, cmdbuf); | ||||
return cmd_step_common(*pp, ch, p - *pp, pwidth, bswidth); | return cmd_step_common(*pp, ch, p - *pp, pwidth, bswidth); | ||||
} | } | ||||
/* | /* | ||||
* Repaint the line from cp onwards. | * Repaint the line from cp onwards. | ||||
* Then position the cursor just after the char old_cp (a pointer into cmdbuf). | * Then position the cursor just after the char old_cp (a pointer into cmdbuf). | ||||
*/ | */ | ||||
static void | static void | ||||
cmd_repaint(old_cp) | cmd_repaint(char *old_cp) | ||||
char *old_cp; | |||||
{ | { | ||||
/* | /* | ||||
* Repaint the line from the current position. | * Repaint the line from the current position. | ||||
*/ | */ | ||||
clear_eol(); | clear_eol(); | ||||
while (*cp != '\0') | while (*cp != '\0') | ||||
{ | { | ||||
char *np = cp; | char *np = cp; | ||||
int width; | int width; | ||||
char *pr = cmd_step_right(&np, &width, NULL); | constant char *pr = cmd_step_right(&np, &width, NULL); | ||||
if (cmd_col + width >= sc_width) | if (cmd_col + width >= sc_width) | ||||
break; | break; | ||||
cp = np; | cp = np; | ||||
putstr(pr); | putstr(pr); | ||||
cmd_col += width; | cmd_col += width; | ||||
} | } | ||||
while (*cp != '\0') | while (*cp != '\0') | ||||
{ | { | ||||
Show All 13 Lines | while (cp > old_cp) | ||||
cmd_left(); | cmd_left(); | ||||
} | } | ||||
/* | /* | ||||
* Put the cursor at "home" (just after the prompt), | * Put the cursor at "home" (just after the prompt), | ||||
* and set cp to the corresponding char in cmdbuf. | * and set cp to the corresponding char in cmdbuf. | ||||
*/ | */ | ||||
static void | static void | ||||
cmd_home() | cmd_home(void) | ||||
{ | { | ||||
while (cmd_col > prompt_col) | while (cmd_col > prompt_col) | ||||
{ | { | ||||
int width, bswidth; | int width, bswidth; | ||||
cmd_step_left(&cp, &width, &bswidth); | cmd_step_left(&cp, &width, &bswidth); | ||||
while (bswidth-- > 0) | while (bswidth-- > 0) | ||||
putbs(); | putbs(); | ||||
cmd_col -= width; | cmd_col -= width; | ||||
} | } | ||||
cp = &cmdbuf[cmd_offset]; | cp = &cmdbuf[cmd_offset]; | ||||
} | } | ||||
/* | /* | ||||
* Shift the cmdbuf display left a half-screen. | * Shift the cmdbuf display left a half-screen. | ||||
*/ | */ | ||||
static void | static void | ||||
cmd_lshift() | cmd_lshift(void) | ||||
{ | { | ||||
char *s; | char *s; | ||||
char *save_cp; | char *save_cp; | ||||
int cols; | int cols; | ||||
/* | /* | ||||
* Start at the first displayed char, count how far to the | * Start at the first displayed char, count how far to the | ||||
* right we'd have to move to reach the center of the screen. | * right we'd have to move to reach the center of the screen. | ||||
Show All 21 Lines | cmd_lshift(void) | ||||
cmd_home(); | cmd_home(); | ||||
cmd_repaint(save_cp); | cmd_repaint(save_cp); | ||||
} | } | ||||
/* | /* | ||||
* Shift the cmdbuf display right a half-screen. | * Shift the cmdbuf display right a half-screen. | ||||
*/ | */ | ||||
static void | static void | ||||
cmd_rshift() | cmd_rshift(void) | ||||
{ | { | ||||
char *s; | char *s; | ||||
char *save_cp; | char *save_cp; | ||||
int cols; | int cols; | ||||
/* | /* | ||||
* Start at the first displayed char, count how far to the | * Start at the first displayed char, count how far to the | ||||
* left we'd have to move to traverse a half-screen width | * left we'd have to move to traverse a half-screen width | ||||
Show All 13 Lines | cmd_rshift(void) | ||||
cmd_home(); | cmd_home(); | ||||
cmd_repaint(save_cp); | cmd_repaint(save_cp); | ||||
} | } | ||||
/* | /* | ||||
* Move cursor right one character. | * Move cursor right one character. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_right() | cmd_right(void) | ||||
{ | { | ||||
char *pr; | char *pr; | ||||
char *ncp; | char *ncp; | ||||
int width; | int width; | ||||
if (*cp == '\0') | if (*cp == '\0') | ||||
{ | { | ||||
/* Already at the end of the line. */ | /* Already at the end of the line. */ | ||||
Show All 18 Lines | cmd_right(void) | ||||
} | } | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Move cursor left one character. | * Move cursor left one character. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_left() | cmd_left(void) | ||||
{ | { | ||||
char *ncp; | char *ncp; | ||||
int width, bswidth; | int width, bswidth; | ||||
if (cp <= cmdbuf) | if (cp <= cmdbuf) | ||||
{ | { | ||||
/* Already at the beginning of the line */ | /* Already at the beginning of the line */ | ||||
return (CC_OK); | return (CC_OK); | ||||
Show All 13 Lines | while (bswidth-- > 0) | ||||
putbs(); | putbs(); | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Insert a char into the command buffer, at the current position. | * Insert a char into the command buffer, at the current position. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_ichar(cs, clen) | cmd_ichar(char *cs, int clen) | ||||
char *cs; | |||||
int clen; | |||||
{ | { | ||||
char *s; | char *s; | ||||
if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1) | if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1) | ||||
{ | { | ||||
/* No room in the command buffer for another char. */ | /* No room in the command buffer for another char. */ | ||||
bell(); | bell(); | ||||
return (CC_ERROR); | return (CC_ERROR); | ||||
Show All 18 Lines | cmd_ichar(char *cs, int clen) | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Backspace in the command buffer. | * Backspace in the command buffer. | ||||
* Delete the char to the left of the cursor. | * Delete the char to the left of the cursor. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_erase() | cmd_erase(void) | ||||
{ | { | ||||
register char *s; | char *s; | ||||
int clen; | int clen; | ||||
if (cp == cmdbuf) | if (cp == cmdbuf) | ||||
{ | { | ||||
/* | /* | ||||
* Backspace past beginning of the buffer: | * Backspace past beginning of the buffer: | ||||
* this usually means abort the command. | * this usually means abort the command. | ||||
*/ | */ | ||||
Show All 30 Lines | if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0') | ||||
return (CC_QUIT); | return (CC_QUIT); | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Delete the char under the cursor. | * Delete the char under the cursor. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_delete() | cmd_delete(void) | ||||
{ | { | ||||
if (*cp == '\0') | if (*cp == '\0') | ||||
{ | { | ||||
/* At end of string; there is no char under the cursor. */ | /* At end of string; there is no char under the cursor. */ | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Move right, then use cmd_erase. | * Move right, then use cmd_erase. | ||||
*/ | */ | ||||
cmd_right(); | cmd_right(); | ||||
cmd_erase(); | cmd_erase(); | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Delete the "word" to the left of the cursor. | * Delete the "word" to the left of the cursor. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_werase() | cmd_werase(void) | ||||
{ | { | ||||
if (cp > cmdbuf && cp[-1] == ' ') | if (cp > cmdbuf && cp[-1] == ' ') | ||||
{ | { | ||||
/* | /* | ||||
* If the char left of cursor is a space, | * If the char left of cursor is a space, | ||||
* erase all the spaces left of cursor (to the first non-space). | * erase all the spaces left of cursor (to the first non-space). | ||||
*/ | */ | ||||
while (cp > cmdbuf && cp[-1] == ' ') | while (cp > cmdbuf && cp[-1] == ' ') | ||||
Show All 9 Lines | cmd_werase(void) | ||||
} | } | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Delete the "word" under the cursor. | * Delete the "word" under the cursor. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_wdelete() | cmd_wdelete(void) | ||||
{ | { | ||||
if (*cp == ' ') | if (*cp == ' ') | ||||
{ | { | ||||
/* | /* | ||||
* If the char under the cursor is a space, | * If the char under the cursor is a space, | ||||
* delete it and all the spaces right of cursor. | * delete it and all the spaces right of cursor. | ||||
*/ | */ | ||||
while (*cp == ' ') | while (*cp == ' ') | ||||
Show All 9 Lines | cmd_wdelete(void) | ||||
} | } | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Delete all chars in the command buffer. | * Delete all chars in the command buffer. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_kill() | cmd_kill(void) | ||||
{ | { | ||||
if (cmdbuf[0] == '\0') | if (cmdbuf[0] == '\0') | ||||
{ | { | ||||
/* Buffer is already empty; abort the current command. */ | /* Buffer is already empty; abort the current command. */ | ||||
return (CC_QUIT); | return (CC_QUIT); | ||||
} | } | ||||
cmd_offset = 0; | cmd_offset = 0; | ||||
cmd_home(); | cmd_home(); | ||||
Show All 9 Lines | if (curr_cmdflags & CF_QUIT_ON_ERASE) | ||||
return (CC_QUIT); | return (CC_QUIT); | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Select an mlist structure to be the current command history. | * Select an mlist structure to be the current command history. | ||||
*/ | */ | ||||
public void | public void | ||||
set_mlist(mlist, cmdflags) | set_mlist(constant void *mlist, int cmdflags) | ||||
void *mlist; | |||||
int cmdflags; | |||||
{ | { | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
curr_mlist = (struct mlist *) mlist; | curr_mlist = (struct mlist *) mlist; | ||||
curr_cmdflags = cmdflags; | curr_cmdflags = cmdflags; | ||||
/* Make sure the next up-arrow moves to the last string in the mlist. */ | /* Make sure the next up-arrow moves to the last string in the mlist. */ | ||||
if (curr_mlist != NULL) | if (curr_mlist != NULL) | ||||
curr_mlist->curr_mp = curr_mlist; | curr_mlist->curr_mp = curr_mlist; | ||||
#endif | #endif | ||||
} | } | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
/* | /* | ||||
* Move up or down in the currently selected command history list. | * Move up or down in the currently selected command history list. | ||||
* Only consider entries whose first updown_match chars are equal to | * Only consider entries whose first updown_match chars are equal to | ||||
* cmdbuf's corresponding chars. | * cmdbuf's corresponding chars. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_updown(action) | cmd_updown(int action) | ||||
int action; | |||||
{ | { | ||||
char *s; | char *s; | ||||
struct mlist *ml; | struct mlist *ml; | ||||
if (curr_mlist == NULL) | if (curr_mlist == NULL) | ||||
{ | { | ||||
/* | /* | ||||
* The current command has no history list. | * The current command has no history list. | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | cmd_updown(int action) | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
#endif | #endif | ||||
/* | /* | ||||
* Add a string to an mlist. | * Add a string to an mlist. | ||||
*/ | */ | ||||
public void | public void | ||||
cmd_addhist(mlist, cmd, modified) | cmd_addhist(struct mlist *constant mlist, char *cmd, int modified) | ||||
struct mlist *mlist; | |||||
char *cmd; | |||||
int modified; | |||||
{ | { | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
struct mlist *ml; | struct mlist *ml; | ||||
/* | /* | ||||
* Don't save a trivial command. | * Don't save a trivial command. | ||||
*/ | */ | ||||
if (strlen(cmd) == 0) | if (strlen(cmd) == 0) | ||||
Show All 26 Lines | |||||
#endif | #endif | ||||
} | } | ||||
/* | /* | ||||
* Accept the command in the command buffer. | * Accept the command in the command buffer. | ||||
* Add it to the currently selected history list. | * Add it to the currently selected history list. | ||||
*/ | */ | ||||
public void | public void | ||||
cmd_accept() | cmd_accept(void) | ||||
{ | { | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
/* | /* | ||||
* Nothing to do if there is no currently selected history list. | * Nothing to do if there is no currently selected history list. | ||||
*/ | */ | ||||
if (curr_mlist == NULL) | if (curr_mlist == NULL) | ||||
return; | return; | ||||
cmd_addhist(curr_mlist, cmdbuf, 1); | cmd_addhist(curr_mlist, cmdbuf, 1); | ||||
curr_mlist->modified = 1; | curr_mlist->modified = 1; | ||||
#endif | #endif | ||||
} | } | ||||
/* | /* | ||||
* Try to perform a line-edit function on the command buffer, | * Try to perform a line-edit function on the command buffer, | ||||
* using a specified char as a line-editing command. | * using a specified char as a line-editing command. | ||||
* Returns: | * Returns: | ||||
* CC_PASS The char does not invoke a line edit function. | * CC_PASS The char does not invoke a line edit function. | ||||
* CC_OK Line edit function done. | * CC_OK Line edit function done. | ||||
* CC_QUIT The char requests the current command to be aborted. | * CC_QUIT The char requests the current command to be aborted. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_edit(c) | cmd_edit(int c) | ||||
int c; | |||||
{ | { | ||||
int action; | int action; | ||||
int flags; | int flags; | ||||
#if TAB_COMPLETE_FILENAME | #if TAB_COMPLETE_FILENAME | ||||
#define not_in_completion() in_completion = 0 | #define not_in_completion() in_completion = 0 | ||||
#else | #else | ||||
#define not_in_completion() | #define not_in_completion() | ||||
▲ Show 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
} | } | ||||
#if TAB_COMPLETE_FILENAME | #if TAB_COMPLETE_FILENAME | ||||
/* | /* | ||||
* Insert a string into the command buffer, at the current position. | * Insert a string into the command buffer, at the current position. | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_istr(str) | cmd_istr(char *str) | ||||
char *str; | |||||
{ | { | ||||
char *s; | char *s; | ||||
int action; | int action; | ||||
char *endline = str + strlen(str); | char *endline = str + strlen(str); | ||||
for (s = str; *s != '\0'; ) | for (s = str; *s != '\0'; ) | ||||
{ | { | ||||
char *os = s; | char *os = s; | ||||
step_char(&s, +1, endline); | step_char((constant char **)&s, +1, endline); | ||||
action = cmd_ichar(os, s - os); | action = cmd_ichar(os, s - os); | ||||
if (action != CC_OK) | if (action != CC_OK) | ||||
{ | { | ||||
bell(); | bell(); | ||||
return (action); | return (action); | ||||
} | } | ||||
} | } | ||||
return (CC_OK); | return (CC_OK); | ||||
} | } | ||||
/* | /* | ||||
* Find the beginning and end of the "current" word. | * Find the beginning and end of the "current" word. | ||||
* This is the word which the cursor (cp) is inside or at the end of. | * This is the word which the cursor (cp) is inside or at the end of. | ||||
* Return pointer to the beginning of the word and put the | * Return pointer to the beginning of the word and put the | ||||
* cursor at the end of the word. | * cursor at the end of the word. | ||||
*/ | */ | ||||
static char * | static char * | ||||
delimit_word() | delimit_word(void) | ||||
{ | { | ||||
char *word; | char *word; | ||||
#if SPACES_IN_FILENAMES | #if SPACES_IN_FILENAMES | ||||
char *p; | char *p; | ||||
int delim_quoted = 0; | int delim_quoted = 0; | ||||
int meta_quoted = 0; | int meta_quoted = 0; | ||||
char *esc = get_meta_escape(); | char *esc = get_meta_escape(); | ||||
int esclen = (int) strlen(esc); | int esclen = (int) strlen(esc); | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Set things up to enter completion mode. | * Set things up to enter completion mode. | ||||
* Expand the word under the cursor into a list of filenames | * Expand the word under the cursor into a list of filenames | ||||
* which start with that word, and set tk_text to that list. | * which start with that word, and set tk_text to that list. | ||||
*/ | */ | ||||
static void | static void | ||||
init_compl() | init_compl(void) | ||||
{ | { | ||||
char *word; | char *word; | ||||
char c; | char c; | ||||
/* | /* | ||||
* Get rid of any previous tk_text. | * Get rid of any previous tk_text. | ||||
*/ | */ | ||||
if (tk_text != NULL) | if (tk_text != NULL) | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
*cp = c; | *cp = c; | ||||
} | } | ||||
/* | /* | ||||
* Return the next word in the current completion list. | * Return the next word in the current completion list. | ||||
*/ | */ | ||||
static char * | static char * | ||||
next_compl(action, prev) | next_compl(int action, char *prev) | ||||
int action; | |||||
char *prev; | |||||
{ | { | ||||
switch (action) | switch (action) | ||||
{ | { | ||||
case EC_F_COMPLETE: | case EC_F_COMPLETE: | ||||
return (forw_textlist(&tk_tlist, prev)); | return (forw_textlist(&tk_tlist, prev)); | ||||
case EC_B_COMPLETE: | case EC_B_COMPLETE: | ||||
return (back_textlist(&tk_tlist, prev)); | return (back_textlist(&tk_tlist, prev)); | ||||
} | } | ||||
/* Cannot happen */ | /* Cannot happen */ | ||||
return ("?"); | return ("?"); | ||||
} | } | ||||
/* | /* | ||||
* Complete the filename before (or under) the cursor. | * Complete the filename before (or under) the cursor. | ||||
* cmd_complete may be called multiple times. The global in_completion | * cmd_complete may be called multiple times. The global in_completion | ||||
* remembers whether this call is the first time (create the list), | * remembers whether this call is the first time (create the list), | ||||
* or a subsequent time (step thru the list). | * or a subsequent time (step thru the list). | ||||
*/ | */ | ||||
static int | static int | ||||
cmd_complete(action) | cmd_complete(int action) | ||||
int action; | |||||
{ | { | ||||
char *s; | char *s; | ||||
if (!in_completion || action == EC_EXPAND) | if (!in_completion || action == EC_EXPAND) | ||||
{ | { | ||||
/* | /* | ||||
* Expand the word under the cursor and | * Expand the word under the cursor and | ||||
* use the first word in the expansion | * use the first word in the expansion | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
* Process a single character of a multi-character command, such as | * Process a single character of a multi-character command, such as | ||||
* a number, or the pattern of a search command. | * a number, or the pattern of a search command. | ||||
* Returns: | * Returns: | ||||
* CC_OK The char was accepted. | * CC_OK The char was accepted. | ||||
* CC_QUIT The char requests the command to be aborted. | * CC_QUIT The char requests the command to be aborted. | ||||
* CC_ERROR The char could not be accepted due to an error. | * CC_ERROR The char could not be accepted due to an error. | ||||
*/ | */ | ||||
public int | public int | ||||
cmd_char(c) | cmd_char(int c) | ||||
int c; | |||||
{ | { | ||||
int action; | int action; | ||||
int len; | int len; | ||||
if (!utf_mode) | if (!utf_mode) | ||||
{ | { | ||||
cmd_mbc_buf[0] = c; | cmd_mbc_buf[0] = c; | ||||
len = 1; | len = 1; | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | cmd_char(int c) | ||||
*/ | */ | ||||
return (cmd_ichar(cmd_mbc_buf, len)); | return (cmd_ichar(cmd_mbc_buf, len)); | ||||
} | } | ||||
/* | /* | ||||
* Return the number currently in the command buffer. | * Return the number currently in the command buffer. | ||||
*/ | */ | ||||
public LINENUM | public LINENUM | ||||
cmd_int(frac) | cmd_int(long *frac) | ||||
long *frac; | |||||
{ | { | ||||
char *p; | char *p; | ||||
LINENUM n = 0; | LINENUM n = 0; | ||||
int err; | int err; | ||||
for (p = cmdbuf; *p >= '0' && *p <= '9'; p++) | for (p = cmdbuf; *p >= '0' && *p <= '9'; p++) | ||||
n = (n * 10) + (*p - '0'); | n = (n * 10) + (*p - '0'); | ||||
*frac = 0; | *frac = 0; | ||||
if (*p++ == '.') | if (*p++ == '.') | ||||
{ | { | ||||
*frac = getfraction(&p, NULL, &err); | *frac = getfraction(&p, NULL, &err); | ||||
/* {{ do something if err is set? }} */ | /* {{ do something if err is set? }} */ | ||||
} | } | ||||
return (n); | return (n); | ||||
} | } | ||||
/* | /* | ||||
* Return a pointer to the command buffer. | * Return a pointer to the command buffer. | ||||
*/ | */ | ||||
public char * | public char * | ||||
get_cmdbuf() | get_cmdbuf(void) | ||||
{ | { | ||||
return (cmdbuf); | return (cmdbuf); | ||||
} | } | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
/* | /* | ||||
* Return the last (most recent) string in the current command history. | * Return the last (most recent) string in the current command history. | ||||
*/ | */ | ||||
public char * | public char * | ||||
cmd_lastpattern() | cmd_lastpattern(void) | ||||
{ | { | ||||
if (curr_mlist == NULL) | if (curr_mlist == NULL) | ||||
return (NULL); | return (NULL); | ||||
return (curr_mlist->curr_mp->prev->string); | return (curr_mlist->curr_mp->prev->string); | ||||
} | } | ||||
#endif | #endif | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
/* | /* | ||||
*/ | */ | ||||
static int | static int | ||||
mlist_size(ml) | mlist_size(struct mlist *ml) | ||||
struct mlist *ml; | |||||
{ | { | ||||
int size = 0; | int size = 0; | ||||
for (ml = ml->next; ml->string != NULL; ml = ml->next) | for (ml = ml->next; ml->string != NULL; ml = ml->next) | ||||
++size; | ++size; | ||||
return size; | return size; | ||||
} | } | ||||
/* | /* | ||||
* Get the name of the history file. | * Get the name of the history file. | ||||
*/ | */ | ||||
static char * | static char * | ||||
histfile_name() | histfile_name(void) | ||||
{ | { | ||||
char *home; | char *home; | ||||
char *name; | char *name; | ||||
int len; | int len; | ||||
/* See if filename is explicitly specified by $LESSHISTFILE. */ | /* See if filename is explicitly specified by $LESSHISTFILE. */ | ||||
name = lgetenv("LESSHISTFILE"); | name = lgetenv("LESSHISTFILE"); | ||||
if (name != NULL && *name != '\0') | if (name != NULL && *name != '\0') | ||||
Show All 23 Lines | #endif | ||||
SNPRINTF2(name, len, "%s/%s", home, LESSHISTFILE); | SNPRINTF2(name, len, "%s/%s", home, LESSHISTFILE); | ||||
return (name); | return (name); | ||||
} | } | ||||
/* | /* | ||||
* Read a .lesshst file and call a callback for each line in the file. | * Read a .lesshst file and call a callback for each line in the file. | ||||
*/ | */ | ||||
static void | static void | ||||
read_cmdhist2(action, uparam, skip_search, skip_shell) | read_cmdhist2(void (*action)(void*,struct mlist*,char*), void *uparam, | ||||
void (*action)(void*,struct mlist*,char*); | int skip_search, int skip_shell) | ||||
void *uparam; | |||||
int skip_search; | |||||
int skip_shell; | |||||
{ | { | ||||
struct mlist *ml = NULL; | struct mlist *ml = NULL; | ||||
char line[CMDBUF_SIZE]; | char line[CMDBUF_SIZE]; | ||||
char *filename; | char *filename; | ||||
FILE *f; | FILE *f; | ||||
char *p; | char *p; | ||||
int *skip = NULL; | int *skip = NULL; | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | #endif | ||||
(*action)(uparam, ml, line+1); | (*action)(uparam, ml, line+1); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
fclose(f); | fclose(f); | ||||
} | } | ||||
static void | static void | ||||
read_cmdhist(action, uparam, skip_search, skip_shell) | read_cmdhist(void (*action)(void*,struct mlist*,char*), void *uparam, | ||||
void (*action)(void*,struct mlist*,char*); | int skip_search, int skip_shell) | ||||
void *uparam; | |||||
int skip_search; | |||||
int skip_shell; | |||||
{ | { | ||||
read_cmdhist2(action, uparam, skip_search, skip_shell); | read_cmdhist2(action, uparam, skip_search, skip_shell); | ||||
(*action)(uparam, NULL, NULL); /* signal end of file */ | (*action)(uparam, NULL, NULL); /* signal end of file */ | ||||
} | } | ||||
static void | static void | ||||
addhist_init(void *uparam, struct mlist *ml, char *string) | addhist_init(void *uparam, struct mlist *ml, char *string) | ||||
{ | { | ||||
if (ml == NULL || string == NULL) | if (ml == NULL || string == NULL) | ||||
return; | return; | ||||
cmd_addhist(ml, string, 0); | cmd_addhist(ml, string, 0); | ||||
} | } | ||||
#endif /* CMD_HISTORY */ | #endif /* CMD_HISTORY */ | ||||
/* | /* | ||||
* Initialize history from a .lesshist file. | * Initialize history from a .lesshist file. | ||||
*/ | */ | ||||
public void | public void | ||||
init_cmdhist() | init_cmdhist(void) | ||||
{ | { | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
read_cmdhist(&addhist_init, NULL, 0, 0); | read_cmdhist(&addhist_init, NULL, 0, 0); | ||||
#endif /* CMD_HISTORY */ | #endif /* CMD_HISTORY */ | ||||
} | } | ||||
/* | /* | ||||
* Write the header for a section of the history file. | * Write the header for a section of the history file. | ||||
*/ | */ | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
static void | static void | ||||
write_mlist_header(ml, f) | write_mlist_header(struct mlist *ml, FILE *f) | ||||
struct mlist *ml; | |||||
FILE *f; | |||||
{ | { | ||||
if (ml == &mlist_search) | if (ml == &mlist_search) | ||||
fprintf(f, "%s\n", HISTFILE_SEARCH_SECTION); | fprintf(f, "%s\n", HISTFILE_SEARCH_SECTION); | ||||
#if SHELL_ESCAPE || PIPEC | #if SHELL_ESCAPE || PIPEC | ||||
else if (ml == &mlist_shell) | else if (ml == &mlist_shell) | ||||
fprintf(f, "%s\n", HISTFILE_SHELL_SECTION); | fprintf(f, "%s\n", HISTFILE_SHELL_SECTION); | ||||
#endif | #endif | ||||
} | } | ||||
/* | /* | ||||
* Write all modified entries in an mlist to the history file. | * Write all modified entries in an mlist to the history file. | ||||
*/ | */ | ||||
static void | static void | ||||
write_mlist(ml, f) | write_mlist(struct mlist *ml, FILE *f) | ||||
struct mlist *ml; | |||||
FILE *f; | |||||
{ | { | ||||
for (ml = ml->next; ml->string != NULL; ml = ml->next) | for (ml = ml->next; ml->string != NULL; ml = ml->next) | ||||
{ | { | ||||
if (!ml->modified) | if (!ml->modified) | ||||
continue; | continue; | ||||
fprintf(f, "\"%s\n", ml->string); | fprintf(f, "\"%s\n", ml->string); | ||||
ml->modified = 0; | ml->modified = 0; | ||||
} | } | ||||
ml->modified = 0; /* entire mlist is now unmodified */ | ml->modified = 0; /* entire mlist is now unmodified */ | ||||
} | } | ||||
/* | /* | ||||
* Make a temp name in the same directory as filename. | * Make a temp name in the same directory as filename. | ||||
*/ | */ | ||||
static char * | static char * | ||||
make_tempname(filename) | make_tempname(char *filename) | ||||
char *filename; | |||||
{ | { | ||||
char lastch; | char lastch; | ||||
char *tempname = ecalloc(1, strlen(filename)+1); | char *tempname = ecalloc(1, strlen(filename)+1); | ||||
strcpy(tempname, filename); | strcpy(tempname, filename); | ||||
lastch = tempname[strlen(tempname)-1]; | lastch = tempname[strlen(tempname)-1]; | ||||
tempname[strlen(tempname)-1] = (lastch == 'Q') ? 'Z' : 'Q'; | tempname[strlen(tempname)-1] = (lastch == 'Q') ? 'Z' : 'Q'; | ||||
return tempname; | return tempname; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
} | } | ||||
#endif /* CMD_HISTORY */ | #endif /* CMD_HISTORY */ | ||||
/* | /* | ||||
* Make a file readable only by its owner. | * Make a file readable only by its owner. | ||||
*/ | */ | ||||
static void | static void | ||||
make_file_private(f) | make_file_private(FILE *f) | ||||
FILE *f; | |||||
{ | { | ||||
#if HAVE_FCHMOD | #if HAVE_FCHMOD | ||||
int do_chmod = 1; | int do_chmod = 1; | ||||
#if HAVE_STAT | #if HAVE_STAT | ||||
struct stat statbuf; | struct stat statbuf; | ||||
int r = fstat(fileno(f), &statbuf); | int r = fstat(fileno(f), &statbuf); | ||||
if (r < 0 || !S_ISREG(statbuf.st_mode)) | if (r < 0 || !S_ISREG(statbuf.st_mode)) | ||||
/* Don't chmod if not a regular file. */ | /* Don't chmod if not a regular file. */ | ||||
do_chmod = 0; | do_chmod = 0; | ||||
#endif | #endif | ||||
if (do_chmod) | if (do_chmod) | ||||
fchmod(fileno(f), 0600); | fchmod(fileno(f), 0600); | ||||
#endif | #endif | ||||
} | } | ||||
/* | /* | ||||
* Does the history file need to be updated? | * Does the history file need to be updated? | ||||
*/ | */ | ||||
static int | static int | ||||
histfile_modified() | histfile_modified(void) | ||||
{ | { | ||||
if (mlist_search.modified) | if (mlist_search.modified) | ||||
return 1; | return 1; | ||||
#if SHELL_ESCAPE || PIPEC | #if SHELL_ESCAPE || PIPEC | ||||
if (mlist_shell.modified) | if (mlist_shell.modified) | ||||
return 1; | return 1; | ||||
#endif | #endif | ||||
return 0; | return 0; | ||||
} | } | ||||
/* | /* | ||||
* Update the .lesshst file. | * Update the .lesshst file. | ||||
*/ | */ | ||||
public void | public void | ||||
save_cmdhist() | save_cmdhist(void) | ||||
{ | { | ||||
#if CMD_HISTORY | #if CMD_HISTORY | ||||
char *histname; | char *histname; | ||||
char *tempname; | char *tempname; | ||||
int skip_search; | int skip_search; | ||||
int skip_shell; | int skip_shell; | ||||
struct save_ctx ctx; | struct save_ctx ctx; | ||||
char *s; | char *s; | ||||
Show All 40 Lines |