Public Access
Shell: Tab completes a path on the SD card (#67)
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:
@@ -77,6 +77,57 @@ void test_tab_completes_the_first_word() {
|
||||
TEST_ASSERT_EQUAL_STRING("n", completeCommand("n", words, matches).c_str()); // and no command starts with n here
|
||||
}
|
||||
|
||||
void test_a_later_word_is_taken_apart_as_a_path() {
|
||||
PathToComplete p;
|
||||
TEST_ASSERT_FALSE(splitForPath("ls", p)); // still the command
|
||||
TEST_ASSERT_FALSE(splitForPath("rm -r", p)); // a switch
|
||||
TEST_ASSERT_FALSE(splitForPath("irc say he", p)); // not a path, and irc doesn't take one
|
||||
TEST_ASSERT_TRUE(splitForPath("rm -r /notes/sh", p));
|
||||
TEST_ASSERT_EQUAL_STRING("rm -r ", p.head.c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("/notes/", p.folder.c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("sh", p.prefix.c_str());
|
||||
TEST_ASSERT_TRUE(splitForPath("ls /", p));
|
||||
TEST_ASSERT_EQUAL_STRING("/", p.folder.c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("", p.prefix.c_str());
|
||||
TEST_ASSERT_TRUE(splitForPath("cat no", p)); // a file command: the slash is understood
|
||||
TEST_ASSERT_EQUAL_STRING("cat ", p.head.c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("/", p.folder.c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("no", p.prefix.c_str());
|
||||
TEST_ASSERT_TRUE(splitForPath("ls ", p));
|
||||
TEST_ASSERT_EQUAL_STRING("/", p.folder.c_str());
|
||||
TEST_ASSERT_TRUE(splitForPath("gemini get /x", p)); // any word that starts with a slash
|
||||
TEST_ASSERT_TRUE(splitForPath("cp /notes/a.txt /gem", p)); // the second path of two
|
||||
TEST_ASSERT_EQUAL_STRING("cp /notes/a.txt ", p.head.c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("gem", p.prefix.c_str());
|
||||
}
|
||||
|
||||
void test_tab_completes_a_path() {
|
||||
std::vector<std::string> root = {"captures/", "gemini/", "gnss/", "irc/", "notes/", "updates/", "wifi/", "readme.txt"};
|
||||
std::vector<std::string> matches;
|
||||
PathToComplete p;
|
||||
splitForPath("ls /no", p);
|
||||
TEST_ASSERT_EQUAL_STRING("ls /notes/", completePath(p, root, matches).c_str()); // a folder: its slash, to go on
|
||||
TEST_ASSERT_EQUAL(0, matches.size());
|
||||
splitForPath("cat /re", p);
|
||||
TEST_ASSERT_EQUAL_STRING("cat /readme.txt ", completePath(p, root, matches).c_str()); // a file: done, a space
|
||||
splitForPath("ls /g", p);
|
||||
TEST_ASSERT_EQUAL_STRING("ls /g", completePath(p, root, matches).c_str()); // gemini, gnss: they agree on no more
|
||||
TEST_ASSERT_EQUAL(2, matches.size());
|
||||
TEST_ASSERT_EQUAL_STRING("gemini/", matches[0].c_str());
|
||||
splitForPath("ls /zz", p);
|
||||
TEST_ASSERT_EQUAL_STRING("ls /zz", completePath(p, root, matches).c_str()); // nothing: as it was
|
||||
TEST_ASSERT_EQUAL(0, matches.size());
|
||||
splitForPath("rm -r /NO", p); // the card doesn't tell cases apart: the name's own case is taken
|
||||
TEST_ASSERT_EQUAL_STRING("rm -r /notes/", completePath(p, root, matches).c_str());
|
||||
std::vector<std::string> notes = {"shopping-list.txt", "Shed.txt", "todo.txt"};
|
||||
splitForPath("cat /notes/sh", p);
|
||||
TEST_ASSERT_EQUAL_STRING("cat /notes/sh", completePath(p, notes, matches).c_str()); // "sh" and "Sh": as far as they agree
|
||||
TEST_ASSERT_EQUAL(2, matches.size());
|
||||
splitForPath("cat /notes/", p);
|
||||
TEST_ASSERT_EQUAL_STRING("cat /notes/", completePath(p, notes, matches).c_str()); // everything fits: the list
|
||||
TEST_ASSERT_EQUAL(3, matches.size());
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_lines_arrive_in_pieces);
|
||||
@@ -84,5 +135,7 @@ int main(int, char**) {
|
||||
RUN_TEST(test_the_oldest_lines_go_past_4_kb);
|
||||
RUN_TEST(test_command_words_come_from_the_help_text);
|
||||
RUN_TEST(test_tab_completes_the_first_word);
|
||||
RUN_TEST(test_a_later_word_is_taken_apart_as_a_path);
|
||||
RUN_TEST(test_tab_completes_a_path);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user