From fba3477ef0bb5436478b394998c7d6bf1171a1e0 Mon Sep 17 00:00:00 2001 From: Daniel Jankowski Date: Wed, 8 May 2024 14:19:28 +0200 Subject: [PATCH] feat: make env & cwd configurable for command widget addresses #52 --- Cargo.lock | 1 + Cargo.toml | 1 + plugin-dev-workspace.kdl | 7 ++++- src/bin/zjstatus.rs | 18 +++++++----- src/render.rs | 4 +-- src/widgets/command.rs | 63 ++++++++++++++++++++++++++++++++++++---- 6 files changed, 78 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49705bc..52e5cd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4239,6 +4239,7 @@ dependencies = [ "chrono-tz", "console", "criterion", + "kdl", "lazy_static", "regex", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 06c9706..e5f2887 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ cached = { version = "0.46.1", features = ["wasm"] } console = "0.15.8" tracing-subscriber = "0.3.18" tracing = "0.1.40" +kdl = "4.6.0" [dev-dependencies] criterion = { version = "0.5.1", default-features = false, features = [ diff --git a/plugin-dev-workspace.kdl b/plugin-dev-workspace.kdl index a5b4fee..b006946 100644 --- a/plugin-dev-workspace.kdl +++ b/plugin-dev-workspace.kdl @@ -45,7 +45,12 @@ layout { command_1_format "#[fg=blue,reverse,bg=default,us=red,blink,dim,strikethrough] {exit_code} {stdout} " command_1_interval "1" - command_git_branch_command "git rev-parse --abbrev-ref HEAD" + command_git_branch_command "bash -c \"echo $FOO\"" + command_git_branch_cwd "/Users/daniel" + command_git_branch_env { + FOO "1" + BAR "foo" + } command_git_branch_format "#[fg=red] {stdout} " command_git_branch_interval "2" diff --git a/src/bin/zjstatus.rs b/src/bin/zjstatus.rs index ab54e65..7e08158 100644 --- a/src/bin/zjstatus.rs +++ b/src/bin/zjstatus.rs @@ -7,14 +7,16 @@ use uuid::Uuid; use zjstatus::{ config::{self, ModuleConfig, UpdateEventMask, ZellijState}, frames, pipe, - widgets::command::{CommandResult, CommandWidget}, - widgets::datetime::DateTimeWidget, - widgets::mode::ModeWidget, - widgets::notification::NotificationWidget, - widgets::session::SessionWidget, - widgets::swap_layout::SwapLayoutWidget, - widgets::tabs::TabsWidget, - widgets::widget::Widget, + widgets::{ + command::{CommandResult, CommandWidget}, + datetime::DateTimeWidget, + mode::ModeWidget, + notification::NotificationWidget, + session::SessionWidget, + swap_layout::SwapLayoutWidget, + tabs::TabsWidget, + widget::Widget, + }, }; #[derive(Default)] diff --git a/src/render.rs b/src/render.rs index f91f9f2..857db82 100644 --- a/src/render.rs +++ b/src/render.rs @@ -79,7 +79,7 @@ impl FormattedPart { let mut format_content_split = format.split(']').collect::>(); if format_content_split.len() == 1 { - result.content = format.to_owned(); + format.clone_into(&mut result.content); return result; } @@ -225,7 +225,7 @@ impl FormattedPart { } let res = self.format_string(&output); - self.cached_content = res.clone(); + self.cached_content.clone_from(&res); res } diff --git a/src/widgets/command.rs b/src/widgets/command.rs index 9e095c9..7e0dfca 100644 --- a/src/widgets/command.rs +++ b/src/widgets/command.rs @@ -1,15 +1,16 @@ +use kdl::{KdlDocument, KdlError}; use lazy_static::lazy_static; use std::{ collections::BTreeMap, fs::{remove_file, File}, ops::Sub, - path::Path, + path::{Path, PathBuf}, }; use chrono::{DateTime, Duration, Local}; use regex::Regex; #[cfg(not(feature = "bench"))] -use zellij_tile::shim::run_command; +use zellij_tile::shim::{run_command, run_command_with_env_variables_and_cwd}; use crate::render::{formatted_parts_from_string_cached, FormattedPart}; @@ -32,6 +33,8 @@ enum RenderMode { struct CommandConfig { command: String, format: FormattedPart, + env: Option>, + cwd: Option, interval: i64, render_mode: RenderMode, } @@ -137,6 +140,19 @@ fn run_command_if_needed(command_config: CommandConfig, name: &str, state: &Zell #[allow(unused_variables)] let command = commandline_parser(&command_config.command); tracing::debug!("Running command: {:?}", command); + + #[cfg(not(feature = "bench"))] + if command_config.env.is_some() || command_config.cwd.is_some() { + run_command_with_env_variables_and_cwd( + &command.iter().map(|x| x.as_str()).collect::>(), + command_config.env.unwrap(), + command_config.cwd.unwrap(), + context, + ); + + return; + } + #[cfg(not(feature = "bench"))] run_command( &command.iter().map(|x| x.as_str()).collect::>(), @@ -161,6 +177,8 @@ fn parse_config(zj_conf: &BTreeMap) -> BTreeMap) -> BTreeMap = zj_conf.get(&key).unwrap().parse(); + + if let Ok(doc) = doc { + command_conf.env = Some(get_env_vars(doc)); + } + } + + if key.ends_with("cwd") { + let mut cwd = PathBuf::new(); + cwd.push(zj_conf.get(&key).unwrap().to_owned().clone()); + + command_conf.cwd = Some(cwd); } if key.ends_with("format") { @@ -199,6 +232,26 @@ fn parse_config(zj_conf: &BTreeMap) -> BTreeMap BTreeMap { + let mut output = BTreeMap::new(); + + for n in doc.nodes() { + let children = n.entries(); + if children.len() != 1 { + continue; + } + + let value = match children.first().unwrap().value().as_string() { + Some(value) => value, + None => continue, + }; + + output.insert(n.name().value().to_string(), value.to_string()); + } + + output +} + fn get_timestamp_from_event_or_default( name: &str, state: &ZellijState, @@ -276,7 +329,7 @@ fn commandline_parser(input: &str) -> Vec { is_in_group = false; found_special_char = '\0'; output.push(buffer.clone()); - buffer = "".to_owned(); + "".clone_into(&mut buffer); continue; } @@ -288,7 +341,7 @@ fn commandline_parser(input: &str) -> Vec { if character == ' ' && !is_in_group { output.push(buffer.clone()); - buffer = "".to_owned(); + "".clone_into(&mut buffer); continue; }