aboutsummaryrefslogtreecommitdiffstats
path: root/src/completion.rs
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-17 15:32:30 +0100
committerJonas Maier <>2026-03-17 15:32:30 +0100
commit89e027f61eda0d918ee2c2622f6ad370a76c5754 (patch)
treebca51022f83e6bf477312fdb03976da8b9c86cd0 /src/completion.rs
parent965196972fa27237b6cb97209c915381a95a5bef (diff)
downloadpish-89e027f61eda0d918ee2c2622f6ad370a76c5754.tar.gz
completion when using path in place of command
Diffstat (limited to 'src/completion.rs')
-rw-r--r--src/completion.rs22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/completion.rs b/src/completion.rs
index c7a183f..d3e4704 100644
--- a/src/completion.rs
+++ b/src/completion.rs
@@ -2,6 +2,7 @@ use crate::parse::{self, CompletionContext};
use crate::{BString, Session};
use std::collections::HashMap;
use std::ffi::OsStr;
+use std::fs::DirEntry;
use std::os::unix::ffi::OsStrExt;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
@@ -12,7 +13,10 @@ pub struct Suggestion {
pub delta: BString,
}
-fn _path_completion(mut prefix: BString) -> std::io::Result<Vec<Suggestion>> {
+fn _path_completion(
+ mut prefix: BString,
+ filter: &dyn Fn(&DirEntry) -> bool,
+) -> std::io::Result<Vec<Suggestion>> {
let mut partial_entry = BString::new();
while let Some(c) = prefix.last().cloned() {
if c == b'/' {
@@ -31,6 +35,9 @@ fn _path_completion(mut prefix: BString) -> std::io::Result<Vec<Suggestion>> {
for entry in fs::read_dir(OsStr::from_bytes(&prefix))? {
let entry = entry?;
+ if !filter(&entry) {
+ continue;
+ }
let name = entry.file_name().as_bytes().to_vec();
if name.starts_with(&partial_entry) {
let mut delta = name[partial_entry.len()..].to_vec();
@@ -53,7 +60,17 @@ fn _path_completion(mut prefix: BString) -> std::io::Result<Vec<Suggestion>> {
}
pub fn path_completion(prefix: BString) -> Vec<Suggestion> {
- match _path_completion(prefix) {
+ match _path_completion(prefix, &|_| true) {
+ Ok(suggestions) => suggestions,
+ Err(err) => {
+ println!("path completion failed: {err:?}\r");
+ Vec::new()
+ }
+ }
+}
+
+pub fn path_exe_completion(prefix: BString) -> Vec<Suggestion> {
+ match _path_completion(prefix, &|d| is_executable(&d.path())) {
Ok(suggestions) => suggestions,
Err(err) => {
println!("path completion failed: {err:?}\r");
@@ -165,6 +182,7 @@ pub fn completion(session: Arc<Mutex<Session>>, cmd: &[u8]) -> CompletionResult
let mut suggestions = match comp.kind {
parse::CompletionKind::Command => command_completion(session.clone(), comp.partial),
+ parse::CompletionKind::PathCommand => path_exe_completion(comp.partial),
parse::CompletionKind::Argument => path_completion(comp.partial),
parse::CompletionKind::Variable => variable_completion(session.clone(), comp.partial),
parse::CompletionKind::None => return CompletionResult::empty(),