[[package]]
name = "swaybar_info"
-version = "0.1.3"
+version = "0.1.4"
dependencies = [
"chrono",
"regex",
[package]
name = "swaybar_info"
-version = "0.1.3"
+version = "0.1.4"
edition = "2021"
description = "Provides swaybar with info to be displayed"
license = "MIT"
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
chrono = "0.4"
-regex = "1.5"
+regex = "1.6"
#status_command $HOME/.config/sway/swaybar_info --time-format="%Y-%m-%d %R:%S"
}
+## Advanced Usage of `--regex-cmd`
+
+If the regex provided to `swaybar_info` has two captures, the first capture will
+be used as the text to be displayed, and the second capture will be expected to
+be the color string (such as FFFFFF for white, or 44FF44 for a lighter green).
+
+For example, if the script invoked with `--regex-cmd` has output like the
+following:
+
+ MPD Title | MPD Album | playingCOLORSPLIT44FF44
+
+That sometimes becomes:
+
+ MPD is not running
+
+Then this text can be parsed with a regex like:
+
+ status_command $HOME/.config/sway/swaybar_info \
+ '--regex-cmd=$HOME/scripts/mpc/mpcCommand.sh[SPLIT]simple[SPLIT]^\(.\*?\)\(?:COLORSPLIT\)?\([A-F0-9]{6}\)?$'
+
+Note that some characters like `*` or `(` had to be escaped because they are
+being passed verbatim to a shell.
+
## Dependencies
Uses [`serde_json`](https://crates.io/crates/serde_json),
Generic(String),
}
+pub struct ExternalRegexResult {
+ pub matched: String,
+ pub color: Option<String>,
+}
+
impl From<io::Error> for Error {
fn from(io_error: io::Error) -> Self {
Self::IO(io_error)
}
}
-pub fn get_cmd_output(cmd: &str, args: &[&str], regex: &Regex) -> Result<String, Error> {
+pub fn get_cmd_output(
+ cmd: &str,
+ args: &[&str],
+ regex: &Regex,
+) -> Result<ExternalRegexResult, Error> {
let mut cmd_builder = Command::new(cmd);
for arg in args {
cmd_builder.arg(arg);
let output = cmd_builder.output()?;
let stdout_output: String = String::from_utf8(output.stdout)?;
let regex_captures = regex
- .captures(&stdout_output)
+ .captures(stdout_output.trim())
.ok_or_else(|| Error::from("Regex returned empty matches".to_owned()))?;
- let regex_match = regex_captures
- .get(0)
- .ok_or_else(|| Error::from("Failed to get regex match".to_owned()))?;
- Ok(regex_match.as_str().to_owned())
+ let mut color: Option<String> = None;
+ let matched: String = if regex_captures.len() == 1 {
+ regex_captures
+ .get(0)
+ .ok_or_else(|| Error::from("Failed to get regex 0".to_owned()))?
+ .as_str()
+ .to_owned()
+ } else {
+ //if regex_captures.len() >= 2 {
+ regex_captures
+ .get(1)
+ .ok_or_else(|| Error::from("Failed to get regex 1".to_owned()))?
+ .as_str()
+ .to_owned()
+ };
+
+ match regex_captures.len() {
+ 3 => color = regex_captures.get(2).map(|m| m.as_str().to_owned()),
+ 4.. => {
+ return Err(Error::from(
+ "Too many captures in regex, up to 2 is allowed".to_owned(),
+ ))
+ }
+ _ => (),
+ }
+
+ Ok(ExternalRegexResult { matched, color })
}
{
for (idx, (cmd, args, regex)) in cmds.iter().enumerate() {
let cmd_result = external::get_cmd_output(cmd, args, regex);
- if let Ok(cmd_string) = cmd_result {
+ if let Ok(cmd_struct) = cmd_result {
if is_empty {
- let cmd_obj =
- SwaybarObject::from_string(format!("regex_cmd_{}", idx), cmd_string);
+ let mut cmd_obj = SwaybarObject::from_string(
+ format!("regex_cmd_{}", idx),
+ cmd_struct.matched,
+ );
+ cmd_obj.color = cmd_struct.color;
array.push_object(cmd_obj);
} else if let Some(cmd_obj) =
array.get_by_name_mut(&format!("regex_cmd_{}", idx))
{
- cmd_obj.update_as_generic(cmd_string, None);
+ cmd_obj.update_as_generic(cmd_struct.matched, cmd_struct.color);
}
} else if let Err(e) = cmd_result {
let mut stderr_handle = io::stderr().lock();