xiaoxiang781216 commented on code in PR #3657:
URL: https://github.com/apache/nuttx-apps/pull/3657#discussion_r3652540526
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ if (cursor < nch)
{
- g_cmdhist.head = (g_cmdhist.head + 1) % RL_CMDHIST_LEN;
-
- for (i = 0; (i < nch) && i < (RL_CMDHIST_LINELEN - 1); i++)
- {
- g_cmdhist.buf[g_cmdhist.head][i] = buf[i];
- }
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ }
+ else if (ch == CTRL_E) /* Ctrl+E = End */
+ {
+ while (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_F) /* Ctrl+F = Right */
+ {
+ if (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_K) /* Ctrl+K = Kill to EOL */
+ {
+ nch = cursor;
+ buf[nch] = '\0';
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ }
+ else if (ch == CTRL_U) /* Ctrl+U = Kill to BOL */
+ {
+ int j;
+ for (j = cursor; j < nch; j++)
+ buf[j - cursor] = buf[j];
+ nch -= cursor;
+ cursor = 0;
+ buf[nch] = '\0';
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ 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--;
+ 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));
+ }
+ }
- g_cmdhist.buf[g_cmdhist.head][i] = '\0';
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ else if (ch == CTRL_R && g_cmdhist.len > 0)
+ {
+ /* Ctrl+R = start a reverse incremental search through the
+ * command history, bash-style. Save the line currently
+ * being edited so it can be restored if the search is
+ * cancelled (Ctrl+G).
+ */
- if (g_cmdhist.len < RL_CMDHIST_LEN)
- {
- g_cmdhist.len++;
- }
- }
+ insearch = true;
+ searchlen = 0;
+ searchoffset = 1;
- g_cmdhist.offset = 1;
+ savednch = nch;
+ if (savednch > RL_CMDHIST_LINELEN - 1)
+ {
+ savednch = RL_CMDHIST_LINELEN - 1;
}
-#endif /* CONFIG_READLINE_CMD_HISTORY */
- /* The newline is stored in the buffer along with the null
- * terminator.
- */
+ for (i = 0; i < savednch; i++)
+ {
+ savedbuf[i] = buf[i];
+ }
- buf[nch++] = '\n';
- buf[nch] = '\0';
+ savedcursor = cursor;
+ nch = 0;
- return nch;
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, false);
+#endif
}
+#endif /* CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH */
+#endif /* CONFIG_READLINE_EDIT_EMACS */
/* Otherwise, put the character in the line buffer if the
* character is not a control byte
*/
else if (!iscntrl(ch & 0xff))
{
+#ifdef CONFIG_READLINE_EDIT
+ /* Defensive check: 'cursor' must always satisfy
+ * 0 <= cursor <= nch. It should never be able to get out of
+ * that range now, but clamp it rather than trust it blindly
+ * -- indexing buf[] with an out-of-range cursor is a
+ * memory-safety bug (a stale cursor previously let this
+ * write arbitrarily far past the end of the caller's
+ * buffer).
+ */
+
+ if (cursor < 0 || cursor > nch)
+ {
+ cursor = nch;
+ }
+
+ /* Only insert if there is room for the new character plus
+ * the line's null terminator. Checking this before writing
+ * (rather than only after, as the non-editing path below
+ * does) is what actually prevents the out-of-bounds write.
+ */
+
+ if (nch + 1 < buflen)
+ {
+ int j;
+ for (j = nch; j > cursor; j--) buf[j] = buf[j - 1];
+ buf[cursor] = (char)ch; nch++; cursor++;
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ if (cursor < nch)
{
- g_cmdhist.head = (g_cmdhist.head + 1) % RL_CMDHIST_LEN;
-
- for (i = 0; (i < nch) && i < (RL_CMDHIST_LINELEN - 1); i++)
- {
- g_cmdhist.buf[g_cmdhist.head][i] = buf[i];
- }
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ }
+ else if (ch == CTRL_E) /* Ctrl+E = End */
+ {
+ while (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_F) /* Ctrl+F = Right */
+ {
+ if (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_K) /* Ctrl+K = Kill to EOL */
+ {
+ nch = cursor;
+ buf[nch] = '\0';
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ }
+ else if (ch == CTRL_U) /* Ctrl+U = Kill to BOL */
+ {
+ int j;
+ for (j = cursor; j < nch; j++)
+ buf[j - cursor] = buf[j];
+ nch -= cursor;
+ cursor = 0;
+ buf[nch] = '\0';
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ 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--;
+ 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));
+ }
+ }
- g_cmdhist.buf[g_cmdhist.head][i] = '\0';
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ else if (ch == CTRL_R && g_cmdhist.len > 0)
+ {
+ /* Ctrl+R = start a reverse incremental search through the
+ * command history, bash-style. Save the line currently
+ * being edited so it can be restored if the search is
+ * cancelled (Ctrl+G).
+ */
- if (g_cmdhist.len < RL_CMDHIST_LEN)
- {
- g_cmdhist.len++;
- }
- }
+ insearch = true;
+ searchlen = 0;
+ searchoffset = 1;
- g_cmdhist.offset = 1;
+ savednch = nch;
+ if (savednch > RL_CMDHIST_LINELEN - 1)
+ {
+ savednch = RL_CMDHIST_LINELEN - 1;
}
-#endif /* CONFIG_READLINE_CMD_HISTORY */
- /* The newline is stored in the buffer along with the null
- * terminator.
- */
+ for (i = 0; i < savednch; i++)
+ {
+ savedbuf[i] = buf[i];
+ }
- buf[nch++] = '\n';
- buf[nch] = '\0';
+ savedcursor = cursor;
+ nch = 0;
- return nch;
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, false);
+#endif
}
+#endif /* CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH */
+#endif /* CONFIG_READLINE_EDIT_EMACS */
/* Otherwise, put the character in the line buffer if the
* character is not a control byte
*/
else if (!iscntrl(ch & 0xff))
{
+#ifdef CONFIG_READLINE_EDIT
+ /* Defensive check: 'cursor' must always satisfy
+ * 0 <= cursor <= nch. It should never be able to get out of
+ * that range now, but clamp it rather than trust it blindly
+ * -- indexing buf[] with an out-of-range cursor is a
+ * memory-safety bug (a stale cursor previously let this
+ * write arbitrarily far past the end of the caller's
+ * buffer).
+ */
+
+ if (cursor < 0 || cursor > nch)
+ {
+ cursor = nch;
+ }
+
+ /* Only insert if there is room for the new character plus
+ * the line's null terminator. Checking this before writing
+ * (rather than only after, as the non-editing path below
+ * does) is what actually prevents the out-of-bounds write.
+ */
+
+ if (nch + 1 < buflen)
+ {
+ int j;
+ 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));
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -636,22 +1297,41 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == ASCII_BS || ch == ASCII_DEL)
{
- /* Eliminate that last character in the buffer. */
+#ifdef CONFIG_READLINE_EDIT
+ /* Delete character before cursor */
- if (nch > 0)
+ if (cursor > 0)
{
+ int k;
+ for (k = cursor; k < nch; k++)
+ buf[k - 1] = buf[k];
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+ }
+ else
+ {
+ nch = 0;
+ }
+ }
+
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch,
+ searchlen > 0 && nch == 0);
+#endif
+ }
+ else if (ch == CTRL_G || ch == ASCII_ETX) /* ^G or ^C: cancel */
+ {
+ /* Cancel: restore the line exactly as it was before
+ * Ctrl+R was pressed.
+ */
+
+ insearch = false;
+ nch = savednch;
+ cursor = savedcursor;
+
+ for (i = 0; i < nch; i++)
+ {
+ buf[i] = savedbuf[i];
+ }
+
+ buf[nch] = '\0';
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+ else if (ch == '\n')
+ {
+ /* Accept the current match and submit it immediately,
+ * exactly as bash does.
+ */
+
+ insearch = false;
+ return submit_line(buf, nch);
+ }
+ else if (ch == ASCII_ESC)
+ {
+ /* Accept the current match into the line, then let the
+ * escape sequence that follows (if any) be processed
+ * normally against it on the next iteration(s).
+ */
+
+ insearch = false;
+ cursor = nch;
+ escape = 1;
+ }
+ else if (!iscntrl(ch & 0xff) && searchlen < RL_CMDHIST_LINELEN - 1)
+ {
+ search[searchlen++] = (char)ch;
+ searchoffset = 1;
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else
+ {
+ /* Anything else (an unhandled control character) just
+ * accepts the current match and returns to normal
+ * editing.
+ */
+
+ insearch = false;
+ cursor = nch;
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+
+ continue;
+ }
+#endif
+
/* Are we processing a VT100 escape sequence */
else if (escape)
{
+#ifdef CONFIG_READLINE_EDIT
+ /* Delete key: ESC [ 3 ~ — waiting for '~' */
+
+ if (escape == 3)
+ {
+ escape = 0;
+ if (ch == '~' && cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+# ifdef CONFIG_READLINE_ECHO
+ /* 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));
+ }
+# endif
+ }
+ continue;
+ }
+
+ if (escape == 4 || escape == 5)
+ {
+ if (ch == '~')
+ {
+ /* Home (1~) or End (4~) */
+
+ cursor = (escape == 4) ? 0 : nch;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+
+ if (ch == ';')
+ {
+ escape = 8;
+ continue;
+ }
+
+ escape = 0;
+ continue;
+ }
+#endif
+
+#ifdef CONFIG_READLINE_EDIT
+ if (escape == 8) /* CSI ; — waiting for modifier digit */
+ {
+ if (ch == '5')
+ {
+ escape = 9; /* Ready for final char */
+ continue;
+ }
+
+ if (ch == ';')
+ {
+ escape = 8;
+ continue;
+ }
+
+ escape = 0;
+ continue;
+ }
+
+ if (escape == 9) /* CSI ;5 — waiting for D or C */
+ {
+ escape = 0;
+
+ if (ch == 'D') /* Ctrl+Left */
+ {
+ while (cursor > 0 && buf[cursor - 1] == ' ')
+ cursor--;
+ while (cursor > 0 && buf[cursor - 1] != ' ')
+ cursor--;
+
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == 'C') /* Ctrl+Right */
+ {
+ while (cursor < nch && buf[cursor] != ' ')
+ cursor++;
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -481,6 +788,18 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR
char *buf,
#ifdef CONFIG_READLINE_CMD_HISTORY
int i;
#endif
+#ifdef CONFIG_READLINE_EDIT
+ volatile int cursor;
Review Comment:
why add volatile
##########
system/readline/readline_common.c:
##########
@@ -72,6 +72,27 @@ struct cmdhist_s
#ifdef CONFIG_READLINE_ECHO
static const char g_erasetoeol[] = VT100_CLEAREOL;
#endif
+#ifdef CONFIG_READLINE_EDIT
+static const char g_curleft[] = {ASCII_ESC, '[', 'D'};
+static const char g_curright[] = {ASCII_ESC, '[', 'C'};
+#endif
+
+#ifdef CONFIG_READLINE_EDIT_EMACS
Review Comment:
move to macro section
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ if (cursor < nch)
{
- g_cmdhist.head = (g_cmdhist.head + 1) % RL_CMDHIST_LEN;
-
- for (i = 0; (i < nch) && i < (RL_CMDHIST_LINELEN - 1); i++)
- {
- g_cmdhist.buf[g_cmdhist.head][i] = buf[i];
- }
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -636,22 +1297,41 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == ASCII_BS || ch == ASCII_DEL)
{
- /* Eliminate that last character in the buffer. */
+#ifdef CONFIG_READLINE_EDIT
+ /* Delete character before cursor */
- if (nch > 0)
+ if (cursor > 0)
{
+ int k;
+ for (k = cursor; k < nch; k++)
+ buf[k - 1] = buf[k];
+ cursor--;
nch--;
-#ifdef CONFIG_READLINE_ECHO
- /* Echo the backspace character on the console. Always output
- * the backspace character because the VT100 terminal doesn't
- * understand DEL properly.
- */
+# ifdef CONFIG_READLINE_ECHO
+ /* Redraw: backspace, clear EOL, redraw tail, restore cursor */
RL_PUTC(vtbl, ASCII_BS);
RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
-#endif
+ if (cursor < nch)
+ {
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ if (cursor < nch)
{
- g_cmdhist.head = (g_cmdhist.head + 1) % RL_CMDHIST_LEN;
-
- for (i = 0; (i < nch) && i < (RL_CMDHIST_LINELEN - 1); i++)
- {
- g_cmdhist.buf[g_cmdhist.head][i] = buf[i];
- }
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ }
+ else if (ch == CTRL_E) /* Ctrl+E = End */
+ {
+ while (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_F) /* Ctrl+F = Right */
+ {
+ if (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_K) /* Ctrl+K = Kill to EOL */
+ {
+ nch = cursor;
+ buf[nch] = '\0';
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ }
+ else if (ch == CTRL_U) /* Ctrl+U = Kill to BOL */
+ {
+ int j;
+ for (j = cursor; j < nch; j++)
+ buf[j - cursor] = buf[j];
+ nch -= cursor;
+ cursor = 0;
+ buf[nch] = '\0';
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ 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--;
+ 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));
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -733,7 +1533,34 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR
char *buf,
#ifdef CONFIG_READLINE_TABCOMPLETION
else if (ch == '\t') /* TAB character */
{
+ /* When tab_completion() finds a match (or lists several), it
+ * always leaves the terminal's real cursor at the end of the
+ * (possibly completed) line -- either by echoing the
+ * appended characters one at a time, or, when it lists
+ * multiple matches, by reprinting the prompt and the whole
+ * buffer from scratch. 'cursor' has to be resynced to
+ * match in that case, or the very next Left/Right/Home/End
+ * keypress will move the terminal's cursor from column
+ * 'nch' while still believing it is moving from wherever
+ * 'cursor' was left (typically the length of the word
+ * before completion) -- the two then stay out of sync for
+ * the rest of the line.
+ *
+ * But if there was no match at all, tab_completion() does
+ * not touch the terminal or the buffer, and 'cursor' must
+ * be left exactly where it was -- unconditionally resyncing
+ * it here would be just as wrong as never resyncing it,
+ * only in the opposite direction.
+ */
+
+#ifdef CONFIG_READLINE_EDIT
+ if (tab_completion(vtbl, buf, buflen, &nch))
Review Comment:
`#endif` and remove line 1561-1563
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ if (cursor < nch)
{
- g_cmdhist.head = (g_cmdhist.head + 1) % RL_CMDHIST_LEN;
-
- for (i = 0; (i < nch) && i < (RL_CMDHIST_LINELEN - 1); i++)
- {
- g_cmdhist.buf[g_cmdhist.head][i] = buf[i];
- }
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ }
+ else if (ch == CTRL_E) /* Ctrl+E = End */
+ {
+ while (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_F) /* Ctrl+F = Right */
+ {
+ if (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_K) /* Ctrl+K = Kill to EOL */
+ {
+ nch = cursor;
+ buf[nch] = '\0';
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ }
+ else if (ch == CTRL_U) /* Ctrl+U = Kill to BOL */
+ {
+ int j;
+ for (j = cursor; j < nch; j++)
+ buf[j - cursor] = buf[j];
+ nch -= cursor;
+ cursor = 0;
+ buf[nch] = '\0';
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ 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--;
+ for (k = start; k < nch; k++)
+ buf[k - (cursor - start)] = buf[k];
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ if (cursor < nch)
{
- g_cmdhist.head = (g_cmdhist.head + 1) % RL_CMDHIST_LEN;
-
- for (i = 0; (i < nch) && i < (RL_CMDHIST_LINELEN - 1); i++)
- {
- g_cmdhist.buf[g_cmdhist.head][i] = buf[i];
- }
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ }
+ else if (ch == CTRL_E) /* Ctrl+E = End */
+ {
+ while (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_F) /* Ctrl+F = Right */
+ {
+ if (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_K) /* Ctrl+K = Kill to EOL */
+ {
+ nch = cursor;
+ buf[nch] = '\0';
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ }
+ else if (ch == CTRL_U) /* Ctrl+U = Kill to BOL */
+ {
+ int j;
+ for (j = cursor; j < nch; j++)
+ buf[j - cursor] = buf[j];
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ if (cursor < nch)
{
- g_cmdhist.head = (g_cmdhist.head + 1) % RL_CMDHIST_LEN;
-
- for (i = 0; (i < nch) && i < (RL_CMDHIST_LINELEN - 1); i++)
- {
- g_cmdhist.buf[g_cmdhist.head][i] = buf[i];
- }
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ }
+ else if (ch == CTRL_E) /* Ctrl+E = End */
+ {
+ while (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_F) /* Ctrl+F = Right */
+ {
+ if (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_K) /* Ctrl+K = Kill to EOL */
+ {
+ nch = cursor;
+ buf[nch] = '\0';
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ }
+ else if (ch == CTRL_U) /* Ctrl+U = Kill to BOL */
+ {
+ int j;
+ for (j = cursor; j < nch; j++)
+ buf[j - cursor] = buf[j];
+ nch -= cursor;
+ cursor = 0;
+ buf[nch] = '\0';
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ 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--;
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+ }
+ else
+ {
+ nch = 0;
+ }
+ }
+
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch,
+ searchlen > 0 && nch == 0);
+#endif
+ }
+ else if (ch == CTRL_G || ch == ASCII_ETX) /* ^G or ^C: cancel */
+ {
+ /* Cancel: restore the line exactly as it was before
+ * Ctrl+R was pressed.
+ */
+
+ insearch = false;
+ nch = savednch;
+ cursor = savedcursor;
+
+ for (i = 0; i < nch; i++)
+ {
+ buf[i] = savedbuf[i];
+ }
+
+ buf[nch] = '\0';
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+ else if (ch == '\n')
+ {
+ /* Accept the current match and submit it immediately,
+ * exactly as bash does.
+ */
+
+ insearch = false;
+ return submit_line(buf, nch);
+ }
+ else if (ch == ASCII_ESC)
+ {
+ /* Accept the current match into the line, then let the
+ * escape sequence that follows (if any) be processed
+ * normally against it on the next iteration(s).
+ */
+
+ insearch = false;
+ cursor = nch;
+ escape = 1;
+ }
+ else if (!iscntrl(ch & 0xff) && searchlen < RL_CMDHIST_LINELEN - 1)
+ {
+ search[searchlen++] = (char)ch;
+ searchoffset = 1;
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else
+ {
+ /* Anything else (an unhandled control character) just
+ * accepts the current match and returns to normal
+ * editing.
+ */
+
+ insearch = false;
+ cursor = nch;
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+
+ continue;
+ }
+#endif
+
/* Are we processing a VT100 escape sequence */
else if (escape)
{
+#ifdef CONFIG_READLINE_EDIT
+ /* Delete key: ESC [ 3 ~ — waiting for '~' */
+
+ if (escape == 3)
+ {
+ escape = 0;
+ if (ch == '~' && cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+# ifdef CONFIG_READLINE_ECHO
+ /* 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));
+ }
+# endif
+ }
+ continue;
+ }
+
+ if (escape == 4 || escape == 5)
+ {
+ if (ch == '~')
+ {
+ /* Home (1~) or End (4~) */
+
+ cursor = (escape == 4) ? 0 : nch;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+
+ if (ch == ';')
+ {
+ escape = 8;
+ continue;
+ }
+
+ escape = 0;
+ continue;
+ }
+#endif
+
+#ifdef CONFIG_READLINE_EDIT
+ if (escape == 8) /* CSI ; — waiting for modifier digit */
+ {
+ if (ch == '5')
+ {
+ escape = 9; /* Ready for final char */
+ continue;
+ }
+
+ if (ch == ';')
+ {
+ escape = 8;
+ continue;
+ }
+
+ escape = 0;
+ continue;
+ }
+
+ if (escape == 9) /* CSI ;5 — waiting for D or C */
+ {
+ escape = 0;
+
+ if (ch == 'D') /* Ctrl+Left */
+ {
+ while (cursor > 0 && buf[cursor - 1] == ' ')
+ cursor--;
+ while (cursor > 0 && buf[cursor - 1] != ' ')
+ cursor--;
+
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == 'C') /* Ctrl+Right */
+ {
+ while (cursor < nch && buf[cursor] != ' ')
+ cursor++;
+ while (cursor < nch && buf[cursor] == ' ')
+ cursor++;
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+ }
+ else
+ {
+ nch = 0;
+ }
+ }
+
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch,
+ searchlen > 0 && nch == 0);
+#endif
+ }
+ else if (ch == CTRL_G || ch == ASCII_ETX) /* ^G or ^C: cancel */
+ {
+ /* Cancel: restore the line exactly as it was before
+ * Ctrl+R was pressed.
+ */
+
+ insearch = false;
+ nch = savednch;
+ cursor = savedcursor;
+
+ for (i = 0; i < nch; i++)
+ {
+ buf[i] = savedbuf[i];
+ }
+
+ buf[nch] = '\0';
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+ else if (ch == '\n')
+ {
+ /* Accept the current match and submit it immediately,
+ * exactly as bash does.
+ */
+
+ insearch = false;
+ return submit_line(buf, nch);
+ }
+ else if (ch == ASCII_ESC)
+ {
+ /* Accept the current match into the line, then let the
+ * escape sequence that follows (if any) be processed
+ * normally against it on the next iteration(s).
+ */
+
+ insearch = false;
+ cursor = nch;
+ escape = 1;
+ }
+ else if (!iscntrl(ch & 0xff) && searchlen < RL_CMDHIST_LINELEN - 1)
+ {
+ search[searchlen++] = (char)ch;
+ searchoffset = 1;
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else
+ {
+ /* Anything else (an unhandled control character) just
+ * accepts the current match and returns to normal
+ * editing.
+ */
+
+ insearch = false;
+ cursor = nch;
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+
+ continue;
+ }
+#endif
+
/* Are we processing a VT100 escape sequence */
else if (escape)
{
+#ifdef CONFIG_READLINE_EDIT
+ /* Delete key: ESC [ 3 ~ — waiting for '~' */
+
+ if (escape == 3)
+ {
+ escape = 0;
+ if (ch == '~' && cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+# ifdef CONFIG_READLINE_ECHO
+ /* 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));
+ }
+# endif
+ }
+ continue;
+ }
+
+ if (escape == 4 || escape == 5)
+ {
+ if (ch == '~')
+ {
+ /* Home (1~) or End (4~) */
+
+ cursor = (escape == 4) ? 0 : nch;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+
+ if (ch == ';')
+ {
+ escape = 8;
+ continue;
+ }
+
+ escape = 0;
+ continue;
+ }
+#endif
+
+#ifdef CONFIG_READLINE_EDIT
+ if (escape == 8) /* CSI ; — waiting for modifier digit */
+ {
+ if (ch == '5')
+ {
+ escape = 9; /* Ready for final char */
+ continue;
+ }
+
+ if (ch == ';')
+ {
+ escape = 8;
+ continue;
+ }
+
+ escape = 0;
+ continue;
+ }
+
+ if (escape == 9) /* CSI ;5 — waiting for D or C */
+ {
+ escape = 0;
+
+ if (ch == 'D') /* Ctrl+Left */
+ {
+ while (cursor > 0 && buf[cursor - 1] == ' ')
+ cursor--;
+ while (cursor > 0 && buf[cursor - 1] != ' ')
+ cursor--;
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+ }
+ else
+ {
+ nch = 0;
+ }
+ }
+
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch,
+ searchlen > 0 && nch == 0);
+#endif
+ }
+ else if (ch == CTRL_G || ch == ASCII_ETX) /* ^G or ^C: cancel */
+ {
+ /* Cancel: restore the line exactly as it was before
+ * Ctrl+R was pressed.
+ */
+
+ insearch = false;
+ nch = savednch;
+ cursor = savedcursor;
+
+ for (i = 0; i < nch; i++)
+ {
+ buf[i] = savedbuf[i];
+ }
+
+ buf[nch] = '\0';
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+ else if (ch == '\n')
+ {
+ /* Accept the current match and submit it immediately,
+ * exactly as bash does.
+ */
+
+ insearch = false;
+ return submit_line(buf, nch);
+ }
+ else if (ch == ASCII_ESC)
+ {
+ /* Accept the current match into the line, then let the
+ * escape sequence that follows (if any) be processed
+ * normally against it on the next iteration(s).
+ */
+
+ insearch = false;
+ cursor = nch;
+ escape = 1;
+ }
+ else if (!iscntrl(ch & 0xff) && searchlen < RL_CMDHIST_LINELEN - 1)
+ {
+ search[searchlen++] = (char)ch;
+ searchoffset = 1;
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else
+ {
+ /* Anything else (an unhandled control character) just
+ * accepts the current match and returns to normal
+ * editing.
+ */
+
+ insearch = false;
+ cursor = nch;
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+
+ continue;
+ }
+#endif
+
/* Are we processing a VT100 escape sequence */
else if (escape)
{
+#ifdef CONFIG_READLINE_EDIT
+ /* Delete key: ESC [ 3 ~ — waiting for '~' */
+
+ if (escape == 3)
+ {
+ escape = 0;
+ if (ch == '~' && cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+# ifdef CONFIG_READLINE_ECHO
+ /* 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));
+ }
+# endif
+ }
+ continue;
+ }
+
+ if (escape == 4 || escape == 5)
+ {
+ if (ch == '~')
+ {
+ /* Home (1~) or End (4~) */
+
+ cursor = (escape == 4) ? 0 : nch;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+
+ if (ch == ';')
+ {
+ escape = 8;
+ continue;
+ }
+
+ escape = 0;
+ continue;
+ }
+#endif
+
+#ifdef CONFIG_READLINE_EDIT
+ if (escape == 8) /* CSI ; — waiting for modifier digit */
+ {
+ if (ch == '5')
+ {
+ escape = 9; /* Ready for final char */
+ continue;
+ }
+
+ if (ch == ';')
+ {
+ escape = 8;
+ continue;
+ }
+
+ escape = 0;
+ continue;
+ }
+
+ if (escape == 9) /* CSI ;5 — waiting for D or C */
+ {
+ escape = 0;
+
+ if (ch == 'D') /* Ctrl+Left */
+ {
+ while (cursor > 0 && buf[cursor - 1] == ' ')
+ cursor--;
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -670,55 +1350,175 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
else if (ch == '\n')
{
-#ifdef CONFIG_READLINE_CMD_HISTORY
- /* Save history of command, only if there was something
- * typed besides return character.
- */
+ return submit_line(buf, nch);
+ }
- if (nch >= 1)
- {
- /* If this command is the one at the top of the circular
- * buffer, don't save it again.
- */
+ /* Emacs-style control keys */
- if (strncmp(buf, g_cmdhist.buf[g_cmdhist.head], nch + 1) != 0)
+#ifdef CONFIG_READLINE_EDIT_EMACS
+ else if (ch == CTRL_A) /* Ctrl+A = Home */
+ {
+ cursor = 0;
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_B) /* Ctrl+B = Left */
+ {
+ if (cursor > 0)
+ {
+ cursor--;
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ else if (ch == CTRL_D) /* Ctrl+D = Delete at cursor */
+ {
+ if (cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ if (cursor < nch)
{
- g_cmdhist.head = (g_cmdhist.head + 1) % RL_CMDHIST_LEN;
-
- for (i = 0; (i < nch) && i < (RL_CMDHIST_LINELEN - 1); i++)
- {
- g_cmdhist.buf[g_cmdhist.head][i] = buf[i];
- }
+ RL_WRITE(vtbl, buf + cursor, nch - cursor);
+ for (k = nch; k > cursor; k--)
+ RL_WRITE(vtbl, g_curleft, sizeof(g_curleft));
+ }
+ }
+ }
+ else if (ch == CTRL_E) /* Ctrl+E = End */
+ {
+ while (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_F) /* Ctrl+F = Right */
+ {
+ if (cursor < nch)
+ {
+ cursor++;
+ RL_WRITE(vtbl, g_curright, sizeof(g_curright));
+ }
+ }
+ else if (ch == CTRL_K) /* Ctrl+K = Kill to EOL */
+ {
+ nch = cursor;
+ buf[nch] = '\0';
+ RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
+ }
+ else if (ch == CTRL_U) /* Ctrl+U = Kill to BOL */
+ {
+ int j;
+ for (j = cursor; j < nch; j++)
+ buf[j - cursor] = buf[j];
+ nch -= cursor;
+ cursor = 0;
+ buf[nch] = '\0';
+ redraw_line(vtbl, buf, nch, cursor);
+ }
+ else if (ch == CTRL_W) /* Ctrl+W = Kill word backward (FIXME)
*/
+ {
+ int start, k;
+ start = cursor;
+ while (start > 0 && buf[start - 1] == ' ')
+ start--;
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
Review Comment:
remove one space
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+ }
+ else
+ {
+ nch = 0;
+ }
+ }
+
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch,
+ searchlen > 0 && nch == 0);
Review Comment:
remove one space
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
Review Comment:
remove one space
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+ }
+ else
+ {
+ nch = 0;
+ }
+ }
+
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch,
+ searchlen > 0 && nch == 0);
+#endif
+ }
+ else if (ch == CTRL_G || ch == ASCII_ETX) /* ^G or ^C: cancel */
+ {
+ /* Cancel: restore the line exactly as it was before
+ * Ctrl+R was pressed.
+ */
+
+ insearch = false;
+ nch = savednch;
+ cursor = savedcursor;
+
+ for (i = 0; i < nch; i++)
+ {
+ buf[i] = savedbuf[i];
+ }
+
+ buf[nch] = '\0';
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+ else if (ch == '\n')
+ {
+ /* Accept the current match and submit it immediately,
+ * exactly as bash does.
+ */
+
+ insearch = false;
+ return submit_line(buf, nch);
+ }
+ else if (ch == ASCII_ESC)
+ {
+ /* Accept the current match into the line, then let the
+ * escape sequence that follows (if any) be processed
+ * normally against it on the next iteration(s).
+ */
+
+ insearch = false;
+ cursor = nch;
+ escape = 1;
+ }
+ else if (!iscntrl(ch & 0xff) && searchlen < RL_CMDHIST_LINELEN - 1)
+ {
+ search[searchlen++] = (char)ch;
+ searchoffset = 1;
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else
+ {
+ /* Anything else (an unhandled control character) just
+ * accepts the current match and returns to normal
+ * editing.
+ */
+
+ insearch = false;
+ cursor = nch;
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+
+ continue;
+ }
+#endif
+
/* Are we processing a VT100 escape sequence */
else if (escape)
{
+#ifdef CONFIG_READLINE_EDIT
+ /* Delete key: ESC [ 3 ~ — waiting for '~' */
+
+ if (escape == 3)
+ {
+ escape = 0;
+ if (ch == '~' && cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
+ nch--;
+# ifdef CONFIG_READLINE_ECHO
+ /* 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));
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+ }
+ else
+ {
+ nch = 0;
+ }
+ }
+
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch,
+ searchlen > 0 && nch == 0);
+#endif
+ }
+ else if (ch == CTRL_G || ch == ASCII_ETX) /* ^G or ^C: cancel */
+ {
+ /* Cancel: restore the line exactly as it was before
+ * Ctrl+R was pressed.
+ */
+
+ insearch = false;
+ nch = savednch;
+ cursor = savedcursor;
+
+ for (i = 0; i < nch; i++)
+ {
+ buf[i] = savedbuf[i];
+ }
+
+ buf[nch] = '\0';
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+ else if (ch == '\n')
+ {
+ /* Accept the current match and submit it immediately,
+ * exactly as bash does.
+ */
+
+ insearch = false;
+ return submit_line(buf, nch);
+ }
+ else if (ch == ASCII_ESC)
+ {
+ /* Accept the current match into the line, then let the
+ * escape sequence that follows (if any) be processed
+ * normally against it on the next iteration(s).
+ */
+
+ insearch = false;
+ cursor = nch;
+ escape = 1;
+ }
+ else if (!iscntrl(ch & 0xff) && searchlen < RL_CMDHIST_LINELEN - 1)
+ {
+ search[searchlen++] = (char)ch;
+ searchoffset = 1;
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else
+ {
+ /* Anything else (an unhandled control character) just
+ * accepts the current match and returns to normal
+ * editing.
+ */
+
+ insearch = false;
+ cursor = nch;
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+
+ continue;
+ }
+#endif
+
/* Are we processing a VT100 escape sequence */
else if (escape)
{
+#ifdef CONFIG_READLINE_EDIT
+ /* Delete key: ESC [ 3 ~ — waiting for '~' */
+
+ if (escape == 3)
+ {
+ escape = 0;
+ if (ch == '~' && cursor < nch)
+ {
+ int k;
+ for (k = cursor + 1; k < nch; k++)
+ buf[k - 1] = buf[k];
Review Comment:
add {}
##########
system/readline/readline_common.c:
##########
@@ -534,20 +860,255 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl,
FAR char *buf,
return EOF;
}
+#ifdef CONFIG_READLINE_EDIT_EMACS_REVERSE_SEARCH
+ /* Are we in reverse incremental search mode (Ctrl+R)? If so,
+ * every subsequent keystroke is interpreted as part of the
+ * search until it is accepted, submitted, or cancelled.
+ */
+
+ else if (insearch)
+ {
+ if (ch == CTRL_R)
+ {
+ /* Repeat: search further back for another match of the
+ * same search string.
+ */
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch, !found);
+#endif
+ }
+ else if (ch == ASCII_BS || ch == ASCII_DEL)
+ {
+ if (searchlen > 0)
+ {
+ searchlen--;
+ searchoffset = 1;
+
+ if (searchlen > 0)
+ {
+ isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
+ }
+ else
+ {
+ nch = 0;
+ }
+ }
+
+#ifdef CONFIG_READLINE_ECHO
+ isearch_redraw(vtbl, search, searchlen, buf, nch,
+ searchlen > 0 && nch == 0);
+#endif
+ }
+ else if (ch == CTRL_G || ch == ASCII_ETX) /* ^G or ^C: cancel */
+ {
+ /* Cancel: restore the line exactly as it was before
+ * Ctrl+R was pressed.
+ */
+
+ insearch = false;
+ nch = savednch;
+ cursor = savedcursor;
+
+ for (i = 0; i < nch; i++)
+ {
+ buf[i] = savedbuf[i];
+ }
+
+ buf[nch] = '\0';
+
+#ifdef CONFIG_READLINE_ECHO
+ redraw_line(vtbl, buf, nch, cursor);
+#endif
+ }
+ else if (ch == '\n')
+ {
+ /* Accept the current match and submit it immediately,
+ * exactly as bash does.
+ */
+
+ insearch = false;
+ return submit_line(buf, nch);
+ }
+ else if (ch == ASCII_ESC)
+ {
+ /* Accept the current match into the line, then let the
+ * escape sequence that follows (if any) be processed
+ * normally against it on the next iteration(s).
+ */
+
+ insearch = false;
+ cursor = nch;
+ escape = 1;
+ }
+ else if (!iscntrl(ch & 0xff) && searchlen < RL_CMDHIST_LINELEN - 1)
+ {
+ search[searchlen++] = (char)ch;
+ searchoffset = 1;
+
+ bool found = isearch_find(search, searchlen, searchoffset,
+ &searchoffset, buf, buflen, &nch);
Review Comment:
remove one space
##########
system/readline/Kconfig:
##########
@@ -54,6 +54,25 @@ config READLINE_MAX_EXTCMDS
endif # READLINE_TABCOMPLETION
+config READLINE_EDIT
+ bool "Command line editing"
+ default y if !DEFAULT_SMALL
Review Comment:
`default !DEFAULT_SMALL`
##########
system/readline/Kconfig:
##########
@@ -54,6 +54,25 @@ config READLINE_MAX_EXTCMDS
endif # READLINE_TABCOMPLETION
+config READLINE_EDIT
+ bool "Command line editing"
+ default y if !DEFAULT_SMALL
+ ---help---
+ Build in support for full command-line editing using cursor
keys,
+ Home/End, Delete. Requires a VT100/ANSI-compatible terminal.
+
+if READLINE_EDIT
+
+config READLINE_EDIT_EMACS
+ bool "Emacs-style control keys"
+ default n
Review Comment:
depends on READLINE_EDIT
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]