aboutsummaryrefslogtreecommitdiffstats
path: root/src/completion.rs
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-10 17:03:16 +0100
committerJonas Maier <>2026-03-10 17:03:16 +0100
commitfb443270b14ad4d404f6b401f83b323a9769e667 (patch)
tree142eb56303c5e6b17ccb9f93af992bc082a11778 /src/completion.rs
parent27ee3f07c39f3f584fac4a8712dd4fe97e46e462 (diff)
downloadpish-fb443270b14ad4d404f6b401f83b323a9769e667.tar.gz
command-name completion based on PATH
Diffstat (limited to 'src/completion.rs')
-rw-r--r--src/completion.rs34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/completion.rs b/src/completion.rs
index 2137b6f..d10aabd 100644
--- a/src/completion.rs
+++ b/src/completion.rs
@@ -1,4 +1,5 @@
use crate::*;
+use std::path::{Path, PathBuf};
use std::{env, fs};
pub struct Suggestion {
@@ -80,10 +81,41 @@ pub fn variable_completion(session: Arc<Mutex<Session>>, prefix: BString) -> Vec
out
}
+#[derive(Default)]
+pub struct PathCache {
+ binaries: HashMap<BString, PathBuf>,
+}
+
+fn is_executable(path: &Path) -> bool {
+ use std::os::unix::fs::PermissionsExt;
+ fs::metadata(path)
+ .map(|m| m.permissions().mode() & 0o111 != 0)
+ .unwrap_or(false)
+}
+
+pub fn populate_path_cache(session: Arc<Mutex<Session>>) {
+ let path_var = env::var_os("PATH").unwrap();
+
+ let mut binaries = HashMap::new();
+
+ for dir in env::split_paths(&path_var) {
+ if let Ok(entries) = fs::read_dir(&dir) {
+ for entry in entries.flatten() {
+ let path = entry.path();
+ if path.is_file() && is_executable(&path) {
+ binaries.insert(path.file_name().unwrap().as_bytes().to_vec(), path);
+ }
+ }
+ }
+ }
+
+ session.lock().unwrap().path_cache = PathCache { binaries };
+}
+
pub fn command_completion(session: Arc<Mutex<Session>>, prefix: BString) -> Vec<Suggestion> {
let se = session.lock().unwrap();
let mut out = Vec::new();
- for fun in se.funs.keys().chain(se.builtins.keys()) {
+ for fun in se.funs.keys().chain(se.builtins.keys()).chain(se.path_cache.binaries.keys()) {
if fun.starts_with(&prefix) {
out.push(Suggestion {
display: fun.to_vec(),