cli : add command and file auto-completion (#19985)

This commit is contained in:
Sigbjørn Skjæret
2026-03-05 10:47:28 +01:00
committed by GitHub
parent cf232515c9
commit b5ed0e058c
3 changed files with 156 additions and 3 deletions

View File

@@ -80,6 +80,8 @@ namespace console {
static termios initial_state;
#endif
static completion_callback completion_cb = nullptr;
//
// Init and cleanup
//
@@ -493,7 +495,7 @@ namespace console {
}
static void set_line_contents(std::string new_line, std::string & line, std::vector<int> & widths, size_t & char_pos,
size_t & byte_pos) {
size_t & byte_pos, int cursor_byte_pos = -1) {
move_to_line_start(char_pos, byte_pos, widths);
clear_current_line(widths);
@@ -503,6 +505,7 @@ namespace console {
char_pos = 0;
size_t idx = 0;
int back_width = 0;
while (idx < line.size()) {
size_t advance = 0;
char32_t cp = decode_utf8(line, idx, advance);
@@ -511,8 +514,15 @@ namespace console {
if (real_width < 0) real_width = 0;
widths.push_back(real_width);
idx += advance;
++char_pos;
byte_pos = idx;
if (cursor_byte_pos >= 0 && static_cast<size_t>(cursor_byte_pos) < idx) {
back_width += real_width;
} else {
++char_pos;
byte_pos = idx;
}
}
if (cursor_byte_pos >= 0) {
move_cursor(-back_width);
}
}
@@ -784,6 +794,20 @@ namespace console {
break;
}
if (completion_cb && input_char == '\t') {
auto candidates = completion_cb(line, byte_pos);
if (!candidates.empty()) {
if (candidates.size() > 1 || candidates[0].first != line) {
// TODO?: Display all candidates
set_line_contents(candidates[0].first, line, widths, char_pos, byte_pos, candidates[0].second);
} else {
// TODO: Move cursor to new byte_pos
}
continue;
}
}
if (input_char == (char32_t) WEOF || input_char == 0x04 /* Ctrl+D */) {
end_of_stream = true;
break;
@@ -1062,6 +1086,10 @@ namespace console {
return readline_advanced(line, multiline_input);
}
void set_completion_callback(completion_callback cb) {
completion_cb = cb;
}
namespace spinner {
static const char LOADING_CHARS[] = {'|', '/', '-', '\\'};
static std::condition_variable cv_stop;

View File

@@ -4,7 +4,9 @@
#include "common.h"
#include <functional>
#include <string>
#include <vector>
enum display_type {
DISPLAY_TYPE_RESET = 0,
@@ -21,6 +23,9 @@ namespace console {
void set_display(display_type display);
bool readline(std::string & line, bool multiline_input);
using completion_callback = std::function<std::vector<std::pair<std::string, size_t>>(std::string_view, size_t)>;
void set_completion_callback(completion_callback cb);
namespace spinner {
void start();
void stop();