@@ -112,6 +112,7 @@ int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj,
struct scene_txtin *tin)
{
struct cli_line_state *cls = &tin->cls;
+ struct cli_editor_state *ed = cli_editor(cls);
const bool open = obj->flags & SCENEOF_OPEN;
struct udevice *cons = scn->expo->cons;
void *ctx = tin->ctx;
@@ -121,7 +122,7 @@ int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj,
if (open) {
scene_render_obj(scn, tin->edit_id, ctx);
- if (cls->multiline) {
+ if (ed->multiline) {
/* for multiline, set cursor position directly */
struct scene_obj_txt *txt;
@@ -260,6 +261,7 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj,
struct scene_txtin *tin)
{
struct cli_line_state *cls = &tin->cls;
+ struct cli_editor_state *ed = cli_editor(cls);
struct udevice *cons = scn->expo->cons;
struct scene_obj_txt *txt;
void *ctx;
@@ -286,11 +288,11 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj,
vidconsole_entry_start(cons, ctx);
cli_cread_init(cls, abuf_data(&tin->buf), abuf_size(&tin->buf));
cls->insert = true;
- cls->putch = scene_txtin_putch;
+ ed->putch = scene_txtin_putch;
cls->priv = scn;
if (obj->type == SCENEOBJT_TEXTEDIT) {
- cls->multiline = true;
- cls->line_nav = scene_txtin_line_nav;
+ ed->multiline = true;
+ ed->line_nav = scene_txtin_line_nav;
}
cli_cread_add_initial(cls);
@@ -54,13 +54,17 @@ config CMDLINE_EDITING
Enable editing and History functions for interactive command line
input operations
-config CLI_READLINE_CALLBACK
- bool "Support a callback for character output"
+config CMDLINE_EDITOR
+ bool "Enhanced command-line editing features"
depends on CMDLINE_EDITING
- help
- Enable a callback for character output during line editing. This
- allows redirection of output to a different destination, such as
- a vidconsole. This is used by expo to support textline editing.
+ default y if EXPO
+ help
+ Enable enhanced editing features for the command line, including:
+ - Character-output callback for redirection to vidconsole
+ - Multi-line navigation callback (Ctrl-P/N)
+ - Ctrl+Left/Right arrow keys to move by words
+ - Undo/redo support (Ctrl+Z / Ctrl+Shift+Z)
+ - Yank/paste of killed text (Ctrl+Y)
config CMDLINE_PS_SUPPORT
bool "Enable support for changing the command prompt string at run-time"
@@ -79,8 +79,10 @@ static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen)
*/
static void cls_putch(struct cli_line_state *cls, int ch)
{
- if (CONFIG_IS_ENABLED(CLI_READLINE_CALLBACK) && cls->putch)
- cls->putch(cls, ch);
+ struct cli_editor_state *ed = cli_editor(cls);
+
+ if (ed && ed->putch)
+ ed->putch(cls, ch);
else
putc(ch);
}
@@ -299,6 +301,7 @@ static void cread_add_str(struct cli_line_state *cls, char *str, int strsize,
int cread_line_process_ch(struct cli_line_state *cls, char ichar)
{
+ struct cli_editor_state *ed;
char *buf = cls->buf;
/* ichar=0x0 when error occurs in U-Boot getc */
@@ -405,10 +408,11 @@ int cread_line_process_ch(struct cli_line_state *cls, char ichar)
break;
case CTL_CH('p'):
case CTL_CH('n'):
- if (cls->multiline && cls->line_nav) {
+ ed = cli_editor(cls);
+ if (ed && ed->multiline && ed->line_nav) {
int new_num;
- new_num = cls->line_nav(cls, ichar == CTL_CH('p'));
+ new_num = ed->line_nav(cls, ichar == CTL_CH('p'));
if (new_num < 0) {
getcmd_cbeep(cls);
break;
@@ -25,6 +25,43 @@ struct cli_ch_state {
bool emitting;
};
+struct cli_line_state;
+
+/**
+ * struct cli_editor_state - state for enhanced editing features
+ *
+ * This is only available when CONFIG_CMDLINE_EDITOR is enabled.
+ *
+ * @putch: Output a character (NULL to use putc())
+ * @line_nav: Handle multi-line navigation (Ctrl-P/N)
+ * @multiline: true if input may contain multiple lines (enables
+ * Ctrl-P/N for line navigation instead of history)
+ */
+struct cli_editor_state {
+ /**
+ * @putch: Output a character (NULL to use putc())
+ *
+ * @cls: CLI line state
+ * @ch: Character to output
+ */
+ void (*putch)(struct cli_line_state *cls, int ch);
+
+ /**
+ * @line_nav: Handle multi-line navigation (Ctrl-P/N)
+ *
+ * @cls: CLI line state
+ * @up: true for previous line, false for next
+ * Return: new cursor position, or -ve if at boundary
+ */
+ int (*line_nav)(struct cli_line_state *cls, bool up);
+
+ /**
+ * @multiline: true if input may contain multiple lines (enables
+ * Ctrl-P/N for line navigation instead of history)
+ */
+ bool multiline;
+};
+
/**
* struct cli_line_state - state of the line editor
*
@@ -34,15 +71,10 @@ struct cli_ch_state {
* @history: true if history should be accessible
* @cmd_complete: true if tab completion should be enabled (requires @prompt to
* be set)
- * @multiline: true if input may contain multiple lines (enables Ctrl-P/N for
- * line navigation instead of history)
* @buf: Buffer containing line
* @prompt: Prompt for the line
- * @putch: Function to call to output a character (NULL to use putc())
- * @line_nav: Function to call for multi-line navigation (Ctrl-P/N). Called with
- * @up true for previous line, false for next. Returns new cursor position,
- * or -ve if at boundary
* @priv: Private data for callbacks
+ * @ed: Editor state for enhanced features (if CONFIG_CMDLINE_EDITOR)
*/
struct cli_line_state {
uint num;
@@ -51,14 +83,30 @@ struct cli_line_state {
bool insert;
bool history;
bool cmd_complete;
- bool multiline;
char *buf;
const char *prompt;
- void (*putch)(struct cli_line_state *cls, int ch);
- int (*line_nav)(struct cli_line_state *cls, bool up);
void *priv;
+#if CONFIG_IS_ENABLED(CMDLINE_EDITOR)
+ struct cli_editor_state ed;
+#endif
};
+/**
+ * cli_editor() - Get the editor state from a line state
+ *
+ * @cls: CLI line state
+ * Return: Pointer to editor state, or NULL if CONFIG_CMDLINE_EDITOR is not
+ * enabled
+ */
+static inline struct cli_editor_state *cli_editor(struct cli_line_state *cls)
+{
+#if CONFIG_IS_ENABLED(CMDLINE_EDITOR)
+ return &cls->ed;
+#else
+ return NULL;
+#endif
+}
+
/**
* Go into the command loop
*