mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-11 06:09:08 -07:00
CLI: Add 'clear' command and command suggestion (#342)
* Add 'clear' command and improve command suggestion in CLI - Introduced a new CLI command 'clear' (alias 'cls') to clear the terminal screen. - Enhanced command not found feedback by suggesting similar commands based on user input. - Added a function to calculate string distance for better command matching. * Review changes * Update changelog --------- Co-authored-by: dexv <89728480+DXVVAY@users.noreply.github.com> Co-authored-by: Willy-JL <49810075+Willy-JL@users.noreply.github.com>
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
- Apps:
|
- Apps:
|
||||||
- Games: Pinball0 (by @rdefeo)
|
- Games: Pinball0 (by @rdefeo)
|
||||||
- NFC: Metroflip (by @luu176)
|
- NFC: Metroflip (by @luu176)
|
||||||
|
- CLI: Add `clear` and `cls` commands, add `did you mean ...?` command suggestion (#342 by @dexvleads)
|
||||||
- BadKB: Added german Mac keyboard Layout (#325 by @Cloudy261)
|
- BadKB: Added german Mac keyboard Layout (#325 by @Cloudy261)
|
||||||
- UL: Sub-GHz: Jolly Motors support with add manually (by @pkooiman & @xMasterX)
|
- UL: Sub-GHz: Jolly Motors support with add manually (by @pkooiman & @xMasterX)
|
||||||
- OFW: Desktop: Add winter animations (by @Astrrra)
|
- OFW: Desktop: Add winter animations (by @Astrrra)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <flipper_application/plugins/plugin_manager.h>
|
#include <flipper_application/plugins/plugin_manager.h>
|
||||||
#include <loader/firmware_api/firmware_api.h>
|
#include <loader/firmware_api/firmware_api.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define TAG "CliSrv"
|
#define TAG "CliSrv"
|
||||||
|
|
||||||
@@ -208,6 +209,36 @@ static void cli_execute_command(Cli* cli, CliCommand* command, FuriString* args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t cli_string_distance(const char* s1, const char* s2) {
|
||||||
|
size_t distance = 0;
|
||||||
|
|
||||||
|
while(*s1 && *s2) {
|
||||||
|
if(*s1++ != *s2++) distance++;
|
||||||
|
}
|
||||||
|
while(*s1++)
|
||||||
|
distance++;
|
||||||
|
while(*s2++)
|
||||||
|
distance++;
|
||||||
|
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cli_find_similar_command(Cli* cli, const char* input, FuriString* suggestion) {
|
||||||
|
size_t min_distance = (size_t)-1;
|
||||||
|
size_t max_allowed = (strlen(input) + 1) / 2;
|
||||||
|
furi_string_reset(suggestion);
|
||||||
|
|
||||||
|
CliCommandTree_it_t it;
|
||||||
|
for(CliCommandTree_it(it, cli->commands); !CliCommandTree_end_p(it); CliCommandTree_next(it)) {
|
||||||
|
const char* cmd_name = furi_string_get_cstr(*CliCommandTree_ref(it)->key_ptr);
|
||||||
|
size_t distance = cli_string_distance(input, cmd_name);
|
||||||
|
if(distance < min_distance && distance <= max_allowed) {
|
||||||
|
min_distance = distance;
|
||||||
|
furi_string_set(suggestion, cmd_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void cli_handle_enter(Cli* cli) {
|
static void cli_handle_enter(Cli* cli) {
|
||||||
cli_normalize_line(cli);
|
cli_normalize_line(cli);
|
||||||
|
|
||||||
@@ -245,9 +276,21 @@ static void cli_handle_enter(Cli* cli) {
|
|||||||
} else {
|
} else {
|
||||||
furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk);
|
furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk);
|
||||||
cli_nl(cli);
|
cli_nl(cli);
|
||||||
printf(
|
FuriString* suggestion = furi_string_alloc();
|
||||||
"`%s` command not found, use `help` or `?` to list all available commands",
|
cli_find_similar_command(cli, furi_string_get_cstr(command), suggestion);
|
||||||
furi_string_get_cstr(command));
|
|
||||||
|
if(furi_string_empty(suggestion)) {
|
||||||
|
printf(
|
||||||
|
"`%s` command not found, use `help` or `?` to list all available commands",
|
||||||
|
furi_string_get_cstr(command));
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"`%s` command not found, did you mean `%s`? Use `help` or `?` to list all available commands",
|
||||||
|
furi_string_get_cstr(command),
|
||||||
|
furi_string_get_cstr(suggestion));
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_string_free(suggestion);
|
||||||
cli_putc(cli, CliKeyBell);
|
cli_putc(cli, CliKeyBell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -682,6 +682,13 @@ void cli_command_i2c(Cli* cli, FuriString* args, void* context) {
|
|||||||
furi_hal_i2c_release(&furi_hal_i2c_handle_external);
|
furi_hal_i2c_release(&furi_hal_i2c_handle_external);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cli_command_clear(Cli* cli, FuriString* args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(args);
|
||||||
|
UNUSED(context);
|
||||||
|
printf("\e[2J\e[H");
|
||||||
|
}
|
||||||
|
|
||||||
CLI_PLUGIN_WRAPPER("info", cli_command_info)
|
CLI_PLUGIN_WRAPPER("info", cli_command_info)
|
||||||
CLI_PLUGIN_WRAPPER("src", cli_command_src)
|
CLI_PLUGIN_WRAPPER("src", cli_command_src)
|
||||||
CLI_PLUGIN_WRAPPER("neofetch", cli_command_neofetch)
|
CLI_PLUGIN_WRAPPER("neofetch", cli_command_neofetch)
|
||||||
@@ -693,6 +700,7 @@ CLI_PLUGIN_WRAPPER("vibro", cli_command_vibro)
|
|||||||
CLI_PLUGIN_WRAPPER("led", cli_command_led)
|
CLI_PLUGIN_WRAPPER("led", cli_command_led)
|
||||||
CLI_PLUGIN_WRAPPER("gpio", cli_command_gpio)
|
CLI_PLUGIN_WRAPPER("gpio", cli_command_gpio)
|
||||||
CLI_PLUGIN_WRAPPER("i2c", cli_command_i2c)
|
CLI_PLUGIN_WRAPPER("i2c", cli_command_i2c)
|
||||||
|
CLI_PLUGIN_WRAPPER("clear", cli_command_clear)
|
||||||
|
|
||||||
void cli_commands_init(Cli* cli) {
|
void cli_commands_init(Cli* cli) {
|
||||||
cli_add_command(cli, "!", CliCommandFlagParallelSafe, cli_command_info_wrapper, (void*)true);
|
cli_add_command(cli, "!", CliCommandFlagParallelSafe, cli_command_info_wrapper, (void*)true);
|
||||||
@@ -724,4 +732,7 @@ void cli_commands_init(Cli* cli) {
|
|||||||
cli_add_command(cli, "led", CliCommandFlagDefault, cli_command_led_wrapper, NULL);
|
cli_add_command(cli, "led", CliCommandFlagDefault, cli_command_led_wrapper, NULL);
|
||||||
cli_add_command(cli, "gpio", CliCommandFlagDefault, cli_command_gpio_wrapper, NULL);
|
cli_add_command(cli, "gpio", CliCommandFlagDefault, cli_command_gpio_wrapper, NULL);
|
||||||
cli_add_command(cli, "i2c", CliCommandFlagDefault, cli_command_i2c_wrapper, NULL);
|
cli_add_command(cli, "i2c", CliCommandFlagDefault, cli_command_i2c_wrapper, NULL);
|
||||||
|
|
||||||
|
cli_add_command(cli, "clear", CliCommandFlagParallelSafe, cli_command_clear, NULL);
|
||||||
|
cli_add_command(cli, "cls", CliCommandFlagParallelSafe, cli_command_clear, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user