You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2019/12/05 12:36:22 UTC
[mynewt-core] 05/06: sys/console: Add autocomplete from history
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit c29bde707b59ba578b298d447635e7894a70ef16
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Wed Nov 13 16:35:41 2019 +0100
sys/console: Add autocomplete from history
Historical entries will show up at prompt when
typed characters match.
---
sys/console/full/src/console.c | 140 +++++++++++++++++++++++++++++++++++------
sys/console/full/syscfg.yml | 5 ++
2 files changed, 126 insertions(+), 19 deletions(-)
diff --git a/sys/console/full/src/console.c b/sys/console/full/src/console.c
index c296d69..86224a1 100644
--- a/sys/console/full/src/console.c
+++ b/sys/console/full/src/console.c
@@ -621,30 +621,83 @@ cursor_backward(unsigned int count)
}
}
+static bool trailing_selection;
+
+/*
+ * The following two weak functions are here in case linker does not allow
+ * to eliminate dead code (console_history_search()).
+ */
+history_handle_t __attribute__((weak))
+console_history_find(history_handle_t start, history_find_type_t search_type,
+ void *arg)
+{
+ return (history_handle_t )0;
+}
+
+int __attribute__((weak))
+console_history_get(history_handle_t handle, size_t offset, char *buf,
+ size_t buf_size)
+{
+ return 0;
+}
+
+static void
+console_history_search(char *line, history_find_type_t direction)
+{
+ line[cur] = '\0';
+ history_line = console_history_find(history_line, direction, line);
+ /* No more lines backward, do nothing */
+ cursor_clear_line();
+ if (!history_line) {
+ trailing_chars = 0;
+ } else {
+ trailing_chars = console_history_get(history_line, cur,line + cur,
+ MYNEWT_VAL(CONSOLE_MAX_INPUT_LEN) - cur);
+ console_write_str(CSI "7m");
+ console_write_nolock(line + cur, trailing_chars);
+ console_write_str(CSI "0m");
+ cursor_backward(trailing_chars);
+ trailing_selection = true;
+ }
+}
+
static void
insert_char(char *pos, char c)
{
char tmp;
- int end = trailing_chars;
+ int end;
- if (cur + end >= MYNEWT_VAL(CONSOLE_MAX_INPUT_LEN) - 1) {
+ if ((!MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH) || !trailing_selection) &&
+ cur + trailing_chars >= MYNEWT_VAL(CONSOLE_MAX_INPUT_LEN) - 1) {
return;
}
if (echo) {
+ if (!MYNEWT_VAL_CHOICE(CONSOLE_HISTORY, none) &&
+ MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH) && trailing_selection) {
+ cursor_clear_line();
+ trailing_chars = 0;
+ trailing_selection = false;
+ }
/* Echo back to console */
console_out_nolock(c);
}
++cur;
- if (end == 0) {
+ if (trailing_chars == 0) {
*pos = c;
- return;
+ if (!MYNEWT_VAL_CHOICE(CONSOLE_HISTORY, none) &&
+ MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH) && cur > 1) {
+ history_line = 0;
+ console_history_search(pos - cur + 1, HFT_MATCH_PREV);
+ return;
+ }
}
tmp = *pos;
*(pos++) = c;
+ end = trailing_chars;
while (end-- > 0) {
if (echo) {
@@ -661,11 +714,37 @@ insert_char(char *pos, char c)
}
}
+static void
+clear_selection(const char *line)
+{
+ if (MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH) && trailing_selection) {
+ trailing_selection = false;
+ console_write_str(CSI "0m");
+ console_write_nolock(line + cur, trailing_chars);
+ cursor_backward(trailing_chars);
+ }
+}
+
+static void
+delete_selection(char *pos)
+{
+ if (MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH) && trailing_selection) {
+ *pos = 0;
+ trailing_selection = false;
+ trailing_chars = 0;
+ cursor_clear_line();
+ }
+}
+
/* Delete character at cursor position */
static void
del_char(char *pos)
{
- int left = trailing_chars;
+ int left;
+
+ delete_selection(pos);
+
+ left = trailing_chars;
while (left-- > 1) {
*pos = *(pos + 1);
@@ -721,13 +800,20 @@ console_history_move(char *line, history_find_type_t direction)
static void
console_handle_move(char *line, int direction)
{
- console_history_move(line, direction > 0 ? HFT_PREV : HFT_NEXT);
+ if (MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH) && trailing_selection) {
+ console_history_search(line, direction > 0 ? HFT_MATCH_PREV :
+ HFT_MATCH_NEXT);
+ } else {
+ console_history_move(line, direction > 0 ? HFT_PREV : HFT_NEXT);
+ }
}
#endif
static void
-handle_home(void)
+handle_home(char *line)
{
+ clear_selection(line);
+
if (cur) {
cursor_backward(cur);
trailing_chars += cur;
@@ -744,8 +830,10 @@ handle_delete(char *line)
}
static void
-handle_end(void)
+handle_end(char *line)
{
+ clear_selection(line);
+
if (trailing_chars) {
cursor_forward(trailing_chars);
cur += trailing_chars;
@@ -804,6 +892,7 @@ ansi_cmd:
break;
}
+ clear_selection(line);
trailing_chars += ansi_val;
cur -= ansi_val;
cursor_backward(ansi_val);
@@ -813,26 +902,27 @@ ansi_cmd:
break;
}
+ clear_selection(line);
trailing_chars -= ansi_val;
cur += ansi_val;
cursor_forward(ansi_val);
break;
case ANSI_HOME:
- handle_home();
+ handle_home(line);
break;
case ANSI_END:
- handle_end();
+ handle_end(line);
break;
case '~':
switch (ansi_val) {
case 1:
- handle_home();
+ handle_home(line);
break;
case 3:
handle_delete(line);
break;
case 4:
- handle_end();
+ handle_end(line);
break;
}
break;
@@ -959,6 +1049,16 @@ console_append_char(char *line, uint8_t byte)
return 1;
}
+static void
+handle_backspace(char *line)
+{
+ if (cur > 0) {
+ cursor_backward(1);
+ cur--;
+ trailing_chars++;
+ del_char(&line[cur]);
+ }
+}
int
console_handle_char(uint8_t byte)
@@ -1020,12 +1120,7 @@ console_handle_char(uint8_t byte)
switch (byte) {
case DEL:
case BS:
- if (cur > 0) {
- cursor_backward(1);
- cur--;
- trailing_chars++;
- del_char(&input->line[cur]);
- }
+ handle_backspace(input->line);
break;
case ESC:
esc_state |= ESC_ESC;
@@ -1071,11 +1166,18 @@ console_handle_char(uint8_t byte)
if (!MYNEWT_VAL_CHOICE(CONSOLE_HISTORY, none)) {
console_history_add(input->line);
history_line = 0;
+ if (MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH)) {
+ trailing_selection = 0;
+ }
}
console_handle_line();
break;
case '\t':
- if (completion && !trailing_chars) {
+ if (completion && (!trailing_chars ||
+ (MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH) && trailing_selection))) {
+ if (MYNEWT_VAL(CONSOLE_HISTORY_AUTO_SEARCH) && trailing_selection) {
+ delete_selection(input->line + cur);
+ }
#if MYNEWT_VAL(CONSOLE_UART_RX_BUF_SIZE) == 0
console_blocking_mode();
#endif
diff --git a/sys/console/full/syscfg.yml b/sys/console/full/syscfg.yml
index 7163884..65efbcb 100644
--- a/sys/console/full/syscfg.yml
+++ b/sys/console/full/syscfg.yml
@@ -49,6 +49,11 @@ syscfg.defs:
- none # no history support
- ram # history kept in ram for current session only
- log # history kept in log
+ CONSOLE_HISTORY_AUTO_SEARCH:
+ description: >
+ When set to 1 history is automatically searched for lines starting with already typed
+ text.
+ value: 0
CONSOLE_MAX_PROMPT_LEN:
description: 'Maximum number of characters for prompt'
value: 16