bin/proxmox-backup-client.rs: implement file name completions - first try ...

This commit is contained in:
Dietmar Maurer 2019-01-17 14:24:20 +01:00
parent 83bdac1e3b
commit 244d9b17a8
3 changed files with 56 additions and 3 deletions

View File

@ -111,6 +111,58 @@ fn create_backup(param: Value, _info: &ApiMethod) -> Result<Value, Error> {
} }
pub fn complete_file_name(arg: &str) -> Vec<String> {
let mut result = vec![];
use nix::fcntl::OFlag;
use nix::sys::stat::Mode;
use nix::fcntl::AtFlags;
let mut dirname = std::path::PathBuf::from(arg);
if let Ok(stat) = nix::sys::stat::fstatat(libc::AT_FDCWD, &dirname, AtFlags::empty()) {
} else {
if let Some(parent) = dirname.parent() {
dirname = parent.to_owned();
}
}
let mut dir = match nix::dir::Dir::openat(libc::AT_FDCWD, &dirname, OFlag::O_DIRECTORY, Mode::empty()) {
Ok(d) => d,
Err(err) => {
return result;
}
};
for item in dir.iter() {
if let Ok(entry) = item {
if let Ok(name) = entry.file_name().to_str() {
if name == "." || name == ".." { continue; }
let mut newpath = dirname.clone();
newpath.push(name);
if let Ok(stat) = nix::sys::stat::fstatat(libc::AT_FDCWD, &newpath, AtFlags::empty()) {
if (stat.st_mode & libc::S_IFMT) == libc::S_IFDIR {
newpath.push("");
if let Some(newpath) = newpath.to_str() {
result.push(newpath.to_owned());
}
continue;
}
}
if let Some(newpath) = newpath.to_str() {
result.push(newpath.to_owned());
}
}
}
}
result
}
fn main() { fn main() {
let cmd_def = CliCommand::new( let cmd_def = CliCommand::new(
@ -129,6 +181,7 @@ fn main() {
) )
)) ))
.arg_param(vec!["filename", "target"]) .arg_param(vec!["filename", "target"])
.completion_cb("filename", complete_file_name)
.completion_cb("store", proxmox_backup::config::datastore::complete_datastore_name); .completion_cb("store", proxmox_backup::config::datastore::complete_datastore_name);

View File

@ -93,7 +93,7 @@ fn print_property_completion(
arg: &str) arg: &str)
{ {
if let Some(callback) = completion_functions.get(name) { if let Some(callback) = completion_functions.get(name) {
let list = (callback)(); let list = (callback)(arg);
for value in list { for value in list {
if value.starts_with(arg) { if value.starts_with(arg) {
println!("{}", value); println!("{}", value);
@ -271,7 +271,7 @@ pub fn run_cli_command(def: &CommandLineInterface) -> Result<(), Error> {
Ok(()) Ok(())
} }
pub type CompletionFunction = fn() -> Vec<String>; pub type CompletionFunction = fn(&str) -> Vec<String>;
pub struct CliCommand { pub struct CliCommand {
pub info: ApiMethod, pub info: ApiMethod,

View File

@ -78,7 +78,7 @@ pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
} }
// shell completion helper // shell completion helper
pub fn complete_datastore_name() -> Vec<String> { pub fn complete_datastore_name(arg: &str) -> Vec<String> {
match config() { match config() {
Ok(data) => data.sections.iter().map(|(id,_)| id.to_string()).collect(), Ok(data) => data.sections.iter().map(|(id,_)| id.to_string()).collect(),
Err(_) => return vec![], Err(_) => return vec![],