feat: add cwd file matching to shell tab completion
This commit is contained in:
@@ -12,4 +12,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MONTAUK_BUILD_NUMBER 82
|
#define MONTAUK_BUILD_NUMBER 104
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ extern "C" void _start() {
|
|||||||
if (pos == 0) continue;
|
if (pos == 0) continue;
|
||||||
|
|
||||||
char* table[128] = { };
|
char* table[128] = { };
|
||||||
int n = get_completions(line, table, 128);
|
int n = get_completions(line, table, 128, cwd, current_drive);
|
||||||
|
|
||||||
montauk::print("\n");
|
montauk::print("\n");
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ int exec_external(const char* cmd, const char* args);
|
|||||||
|
|
||||||
// ---- Tab completion (tabcompletion.cpp) ----
|
// ---- Tab completion (tabcompletion.cpp) ----
|
||||||
|
|
||||||
int get_completions(char* string, char** array, int arrayMax);
|
int get_completions(char* string, char** array, int arrayMax, char* cwd = nullptr, int volume_number = 0);
|
||||||
|
|
||||||
// ---- Shell builtins ----
|
// ---- Shell builtins ----
|
||||||
|
|
||||||
|
|||||||
@@ -53,10 +53,64 @@ const char* strip_elf_extension(const char* path) {
|
|||||||
return (const char*)p;
|
return (const char*)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* build_montauk_path(
|
||||||
|
char* buffer,
|
||||||
|
int max,
|
||||||
|
|
||||||
|
int volume_number,
|
||||||
|
const char* subpath
|
||||||
|
) {
|
||||||
|
|
||||||
|
char volume_number_str[4]; // 3 digits (max. 999) + null byte
|
||||||
|
int_to_str(volume_number, volume_number_str, 4);
|
||||||
|
|
||||||
|
// example path:
|
||||||
|
size_t vn_length = slen(volume_number_str); // 0
|
||||||
|
size_t subpath_length = slen(subpath); // users/admin
|
||||||
|
size_t bytes_required = vn_length + subpath_length + 2; // + ":" and "/" (full path 0:/users/admin)
|
||||||
|
|
||||||
|
if (max < bytes_required) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < vn_length; i++) {
|
||||||
|
buffer[pos] = volume_number_str[i];
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[pos] = ':'; pos++;
|
||||||
|
buffer[pos] = '/'; pos++;
|
||||||
|
|
||||||
|
for (int i = 0; i < subpath_length; i++) {
|
||||||
|
buffer[pos] = subpath[i];
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* remove_path_prefix(
|
||||||
|
const char* prefix, // users/admin
|
||||||
|
const char* string // users/admin/config/
|
||||||
|
) { // result: config/
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
while (string[pos] == prefix[pos]) {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &string[pos];
|
||||||
|
}
|
||||||
|
|
||||||
int get_completions( // returns no. of results
|
int get_completions( // returns no. of results
|
||||||
char* string, // String to match/complete
|
char* string, // String to match/complete
|
||||||
char** array, // Array of strings containing completions
|
char** array, // Array of strings containing completions
|
||||||
int arrayMax
|
int arrayMax,
|
||||||
|
|
||||||
|
char* cwd,
|
||||||
|
int volume_number
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// --- System commands (0:/os/*.elf) ----
|
// --- System commands (0:/os/*.elf) ----
|
||||||
@@ -92,7 +146,7 @@ int get_completions( // returns no. of results
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---- Shell builtins ----
|
// ---- Shell builtins ----
|
||||||
|
|
||||||
size_t builtins_count = sizeof(shell_builtins) / sizeof(const char*);
|
size_t builtins_count = sizeof(shell_builtins) / sizeof(const char*);
|
||||||
|
|
||||||
for (size_t i = 0; i < builtins_count; i++) {
|
for (size_t i = 0; i < builtins_count; i++) {
|
||||||
@@ -105,5 +159,32 @@ int get_completions( // returns no. of results
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- cwd file matching ----
|
||||||
|
|
||||||
|
if (cwd != nullptr) {
|
||||||
|
char full_path[RD_MAX] = { };
|
||||||
|
build_montauk_path(full_path, RD_MAX, volume_number, cwd);
|
||||||
|
|
||||||
|
const char* cwd_entries[RD_MAX] = { };
|
||||||
|
|
||||||
|
int n = montauk::readdir(full_path, cwd_entries, RD_MAX);
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
const char* cwd_entry_path = remove_path_prefix(cwd, cwd_entries[i]);
|
||||||
|
|
||||||
|
if (cwd_entry_path[0] == '/') {
|
||||||
|
cwd_entry_path++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (montauk::starts_with(cwd_entry_path, (const char*)string)) {
|
||||||
|
if (r > arrayMax)
|
||||||
|
break;
|
||||||
|
|
||||||
|
array[r] = (char *)cwd_entry_path;
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user