autcomplete
All checks were successful
Build-Test-Publish / build (linux/amd64) (push) Successful in 21s
Build-Test-Publish / build (linux/arm64) (push) Successful in 27s

This commit is contained in:
2025-09-30 13:01:52 +13:00
parent 380f518af8
commit 0859301037
4 changed files with 70 additions and 9 deletions

11
dshash-completion.bash Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
# Bash completion for dshash
_dshash_autocomplete() {
local cur="${COMP_WORDS[COMP_CWORD]}"
mapfile -t completions < <(dshash autocomplete "${COMP_WORDS[@]:1:${COMP_CWORD}-1}")
mapfile -t COMPREPLY < <(compgen -W "${completions[*]}" -- "$cur")
}
# Use -o default to enable file/directory completion in addition to custom completions
complete -o default -F _dshash_autocomplete dshash

Binary file not shown.

View File

@@ -27,16 +27,66 @@ int main(int argc, char* argv[]) {
// Check for autocomplete command
if (std::string(argv[1]) == "autocomplete") {
// Return available options for autocomplete
std::cout << "-v\n";
std::cout << "version\n";
// Suggest files and directories in current directory
try {
for (const auto& entry : std::filesystem::directory_iterator(".")) {
std::cout << entry.path().filename().string() << "\n";
// Parse the arguments passed by bash completion
// argv[2] onwards contains the current command line words (excluding the command itself)
// If no args typed yet, suggest commands and flags
if (argc == 2) {
std::cout << "-v\n";
std::cout << "version\n";
// Also list files/directories in current directory
try {
for (const auto& entry : std::filesystem::directory_iterator(".")) {
std::string name = entry.path().filename().string();
// Skip hidden files starting with .
if (!name.empty() && name[0] != '.') {
if (entry.is_directory()) {
std::cout << name << "/\n";
} else {
std::cout << name << "\n";
}
}
}
} catch (...) {
// Ignore errors
}
} else {
// Get the last argument (the partial word being completed)
std::string partial = argv[argc - 1];
// Handle file/directory path completion
std::filesystem::path partial_path(partial);
std::filesystem::path dir_path = partial_path.parent_path();
std::string prefix = partial_path.filename().string();
if (dir_path.empty()) {
dir_path = ".";
}
try {
if (std::filesystem::exists(dir_path) && std::filesystem::is_directory(dir_path)) {
for (const auto& entry : std::filesystem::directory_iterator(dir_path)) {
std::string name = entry.path().filename().string();
// Skip hidden files unless user is explicitly typing them
if (prefix.empty() && !name.empty() && name[0] == '.') {
continue;
}
// Check if filename starts with the prefix
if (name.find(prefix) == 0) {
std::filesystem::path full_path = entry.path();
if (entry.is_directory()) {
std::cout << full_path.string() << "/\n";
} else {
std::cout << full_path.string() << "\n";
}
}
}
}
} catch (...) {
// Ignore errors in autocomplete
}
} catch (...) {
// Ignore errors in autocomplete
}
return 0;
}

Binary file not shown.