[Concept,12/16] cli: Add multiline support to CLI line editing
Commit Message
From: Simon Glass <simon.glass@canonical.com>
Add support for multi-line input in CLI line editing:
- Add multiline bool to indicate input may contain multiple lines
- Add line_nav callback for Ctrl-P/N navigation between visual lines
When multiline is true, Ctrl-P/N call the line_nav callback instead of
accessing command history. The callback returns the new cursor position
or a negative value if at the boundary.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---
common/cli_readline.c | 17 +++++++++++++++++
include/cli.h | 9 ++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)
@@ -405,6 +405,23 @@ 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) {
+ int new_num;
+
+ new_num = cls->line_nav(cls, ichar == CTL_CH('p'));
+ if (new_num < 0) {
+ getcmd_cbeep(cls);
+ break;
+ }
+
+ /*
+ * Just update the position - the callback handles
+ * cursor display since backspaces don't work across
+ * wrapped line boundaries
+ */
+ cls->num = new_num;
+ break;
+ }
if (cls->history) {
char *hline;
@@ -34,10 +34,15 @@ 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())
- * @priv: Private data for putch callback
+ * @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
*/
struct cli_line_state {
uint num;
@@ -46,9 +51,11 @@ 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;
};