Shell: Tab completes a path on the SD card (#67)
CI / build (pull_request) Successful in 1m48s
Site / build (pull_request) Successful in 10s

Past the command's name, Tab completes the word being typed as a path: a
folder keeps its slash to go on from, a file completed whole gets a space,
several candidates are listed. Any case typed, the name's own is taken.
After a file command the first slash is understood (`cat no` is /no).
The folder is read on the storage task, bounded to 400 entries looked at
and 24 candidates.

489 host tests (2 new). Checked on the device: a folder, a file inside it,
several candidates, no slash, another case, nothing matching.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-07 12:03:44 +02:00
co-authored by Claude Opus 5.5
parent 7b5df713ad
commit d17d10948d
12 changed files with 184 additions and 14 deletions
+6 -3
View File
@@ -123,13 +123,16 @@ bool ShellApp::onKey(const KeyEvent& e) {
case Key::Down:
if (history_.down(recalled)) input_.setText(recalled);
break;
case Key::Tab: {
case Key::Tab: { // the command's name, or past it a path on the card
std::vector<std::string> matches;
input_.setText(completeCommand(input_.text(), words_, matches));
PathToComplete path;
bool more = false;
if (splitForPath(input_.text(), path)) input_.setText(completePath(path, list_(path.folder, path.prefix, more), matches));
else input_.setText(completeCommand(input_.text(), words_, matches));
if (matches.size() > 1) {
std::string all;
for (auto& m : matches) all += (all.empty() ? "" : " ") + m;
log_.add(all);
log_.add(all + (more ? " ..." : ""));
}
break;
}