mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
readline: remove 5x duplicated in redraw code
The original readline_common.c file had some duplicated code that was causing the nsh to be more than 1KB bigger. This clean up will allow adding line editing without increasing the final firmware size too much. Signed-off-by: Alan C. Assis <acassis@gmail.com> Assisted-by: Claude Code
This commit is contained in:
parent
51bfd48e78
commit
893f0c31ee
1 changed files with 107 additions and 102 deletions
|
|
@ -158,6 +158,36 @@ static int count_builtin_matches(FAR char *buf, FAR int *matches,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_READLINE_TABCOMPLETION) && \
|
||||
(defined(CONFIG_BUILTIN) || defined(CONFIG_READLINE_HAVE_EXTMATCH))
|
||||
static void tab_print_match(FAR struct rl_common_s *vtbl,
|
||||
FAR const char *name, FAR char *tmp_name,
|
||||
size_t tmp_size)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
if (tmp_name[0] == '\0')
|
||||
{
|
||||
strlcpy(tmp_name, name, tmp_size);
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, ' ');
|
||||
RL_PUTC(vtbl, ' ');
|
||||
|
||||
for (j = 0; j < strlen(name); j++)
|
||||
{
|
||||
if (j < tmp_size && name[j] != tmp_name[j])
|
||||
{
|
||||
tmp_name[j] = '\0';
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, name[j]);
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, '\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab_completion
|
||||
*
|
||||
|
|
@ -303,32 +333,7 @@ static bool tab_completion(FAR struct rl_common_s *vtbl, char *buf,
|
|||
for (i = 0; i < nr_ext_matches; i++)
|
||||
{
|
||||
name = g_extmatch_vtbl->getname(ext_matches[i]);
|
||||
|
||||
/* Initialize temp */
|
||||
|
||||
if (tmp_name[0] == '\0')
|
||||
{
|
||||
strlcpy(tmp_name, name, sizeof(tmp_name));
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, ' ');
|
||||
RL_PUTC(vtbl, ' ');
|
||||
|
||||
for (j = 0; j < (int)strlen(name); j++)
|
||||
{
|
||||
/* Removing characters that aren't common to all the
|
||||
* matches.
|
||||
*/
|
||||
|
||||
if (j < (int)sizeof(tmp_name) && name[j] != tmp_name[j])
|
||||
{
|
||||
tmp_name[j] = '\0';
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, name[j]);
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, '\n');
|
||||
tab_print_match(vtbl, name, tmp_name, sizeof(tmp_name));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -338,32 +343,7 @@ static bool tab_completion(FAR struct rl_common_s *vtbl, char *buf,
|
|||
for (i = 0; i < nr_builtin_matches; i++)
|
||||
{
|
||||
name = builtin_getname(builtin_matches[i]);
|
||||
|
||||
/* Initialize temp */
|
||||
|
||||
if (tmp_name[0] == '\0')
|
||||
{
|
||||
strlcpy(tmp_name, name, sizeof(tmp_name));
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, ' ');
|
||||
RL_PUTC(vtbl, ' ');
|
||||
|
||||
for (j = 0; j < strlen(name); j++)
|
||||
{
|
||||
/* Removing characters that aren't common to all the
|
||||
* matches.
|
||||
*/
|
||||
|
||||
if (j < sizeof(tmp_name) && name[j] != tmp_name[j])
|
||||
{
|
||||
tmp_name[j] = '\0';
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, name[j]);
|
||||
}
|
||||
|
||||
RL_PUTC(vtbl, '\n');
|
||||
tab_print_match(vtbl, name, tmp_name, sizeof(tmp_name));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -515,6 +495,41 @@ static bool isearch_find(FAR const char *search, int searchlen,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_READLINE_EDIT
|
||||
/****************************************************************************
|
||||
* Name: word_skip
|
||||
*
|
||||
* Description:
|
||||
* Used by Ctrl+Left/Ctrl+Right. Starting from 'cursor', skip over any
|
||||
* run of spaces then the following word (or, going backward, the
|
||||
* preceding word then any run of spaces before it), stopping at
|
||||
* 'bound' (0 going backward, 'nch' going forward). Returns the new
|
||||
* cursor position.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int word_skip(FAR const char *buf, int cursor, int bound,
|
||||
bool forward)
|
||||
{
|
||||
if (forward)
|
||||
{
|
||||
while (cursor < bound && buf[cursor] != ' ')
|
||||
cursor++;
|
||||
while (cursor < bound && buf[cursor] == ' ')
|
||||
cursor++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (cursor > bound && buf[cursor - 1] == ' ')
|
||||
cursor--;
|
||||
while (cursor > bound && buf[cursor - 1] != ' ')
|
||||
cursor--;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_READLINE_ECHO
|
||||
#ifdef CONFIG_READLINE_EDIT
|
||||
/****************************************************************************
|
||||
|
|
@ -564,6 +579,38 @@ static void redraw_line(FAR struct rl_common_s *vtbl, FAR const char *buf,
|
|||
RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: redraw_tail
|
||||
*
|
||||
* Description:
|
||||
* Redraw just the tail of the line, from 'cursor' to 'nch': erase to
|
||||
* the end of line, rewrite whatever remains after the cursor (if
|
||||
* any), then move the cursor back left to where it started. This is
|
||||
* the shared tail end of every edit that only changes content at or
|
||||
* after the cursor without moving it (Delete, Backspace, Ctrl+D,
|
||||
* Ctrl+W, inserting a character) -- unlike redraw_line(), it does
|
||||
* not touch the prompt or anything before the cursor, since none of
|
||||
* those callers need to.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void redraw_tail(FAR struct rl_common_s *vtbl, FAR const char *buf,
|
||||
int nch, int cursor)
|
||||
{
|
||||
int j;
|
||||
|
||||
RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
|
||||
|
||||
if (cursor < nch)
|
||||
{
|
||||
RL_WRITE(vtbl, buf + cursor, nch - cursor);
|
||||
for (j = nch; j > cursor; j--)
|
||||
{
|
||||
RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_READLINE_EDIT */
|
||||
|
||||
#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
|
||||
|
|
@ -994,13 +1041,7 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf,
|
|||
/* Back up 1 — terminal echo of '~' advanced cursor */
|
||||
|
||||
RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
|
||||
RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
|
||||
if (cursor < nch)
|
||||
{
|
||||
RL_WRITE(vtbl, buf + cursor, nch - cursor);
|
||||
for (k = nch; k > cursor; k--)
|
||||
RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
|
||||
}
|
||||
redraw_tail(vtbl, buf, nch, cursor);
|
||||
# endif
|
||||
}
|
||||
continue;
|
||||
|
|
@ -1052,20 +1093,12 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf,
|
|||
|
||||
if (ch == 'D') /* Ctrl+Left */
|
||||
{
|
||||
while (cursor > 0 && buf[cursor - 1] == ' ')
|
||||
cursor--;
|
||||
while (cursor > 0 && buf[cursor - 1] != ' ')
|
||||
cursor--;
|
||||
|
||||
cursor = word_skip(buf, cursor, 0, false);
|
||||
redraw_line(vtbl, buf, nch, cursor);
|
||||
}
|
||||
else if (ch == 'C') /* Ctrl+Right */
|
||||
{
|
||||
while (cursor < nch && buf[cursor] != ' ')
|
||||
cursor++;
|
||||
while (cursor < nch && buf[cursor] == ' ')
|
||||
cursor++;
|
||||
|
||||
cursor = word_skip(buf, cursor, nch, true);
|
||||
redraw_line(vtbl, buf, nch, cursor);
|
||||
}
|
||||
|
||||
|
|
@ -1312,13 +1345,7 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf,
|
|||
/* Redraw: backspace, clear EOL, redraw tail, restore cursor */
|
||||
|
||||
RL_PUTC(vtbl, ASCII_BS);
|
||||
RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
|
||||
if (cursor < nch)
|
||||
{
|
||||
RL_WRITE(vtbl, buf + cursor, nch - cursor);
|
||||
for (k = nch; k > cursor; k--)
|
||||
RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
|
||||
}
|
||||
redraw_tail(vtbl, buf, nch, cursor);
|
||||
# endif
|
||||
}
|
||||
#else
|
||||
|
|
@ -1377,13 +1404,7 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf,
|
|||
for (k = cursor + 1; k < nch; k++)
|
||||
buf[k - 1] = buf[k];
|
||||
nch--;
|
||||
RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
|
||||
if (cursor < nch)
|
||||
{
|
||||
RL_WRITE(vtbl, buf + cursor, nch - cursor);
|
||||
for (k = nch; k > cursor; k--)
|
||||
RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
|
||||
}
|
||||
redraw_tail(vtbl, buf, nch, cursor);
|
||||
}
|
||||
}
|
||||
else if (ch == CTRL_E) /* Ctrl+E = End */
|
||||
|
|
@ -1421,23 +1442,13 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf,
|
|||
else if (ch == CTRL_W) /* Ctrl+W = Kill word backward (FIXME) */
|
||||
{
|
||||
int start, k;
|
||||
start = cursor;
|
||||
while (start > 0 && buf[start - 1] == ' ')
|
||||
start--;
|
||||
while (start > 0 && buf[start - 1] != ' ')
|
||||
start--;
|
||||
start = word_skip(buf, cursor, 0, false);
|
||||
for (k = start; k < nch; k++)
|
||||
buf[k - (cursor - start)] = buf[k];
|
||||
nch -= (cursor - start);
|
||||
cursor = start;
|
||||
buf[nch] = '\0';
|
||||
RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
|
||||
if (cursor < nch)
|
||||
{
|
||||
RL_WRITE(vtbl, buf + cursor, nch - cursor);
|
||||
for (k = nch; k > cursor; k--)
|
||||
RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
|
||||
}
|
||||
redraw_tail(vtbl, buf, nch, cursor);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
|
||||
|
|
@ -1507,13 +1518,7 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf,
|
|||
for (j = nch; j > cursor; j--) buf[j] = buf[j - 1];
|
||||
buf[cursor] = (char)ch; nch++; cursor++;
|
||||
# ifdef CONFIG_READLINE_ECHO
|
||||
if (cursor < nch)
|
||||
{
|
||||
RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
|
||||
RL_WRITE(vtbl, buf + cursor, nch - cursor);
|
||||
for (j = nch; j > cursor; j--)
|
||||
RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
|
||||
}
|
||||
redraw_tail(vtbl, buf, nch, cursor);
|
||||
# endif
|
||||
}
|
||||
#else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue