mirror of
https://github.com/JakeStanger/ironbar.git
synced 2024-09-11 14:35:53 +03:00
feat: add man pages and shell completions
Auto-generated with clap.
This commit is contained in:
parent
e1d55c6972
commit
a6b1254248
27
Cargo.lock
generated
27
Cargo.lock
generated
@ -476,6 +476,15 @@ dependencies = [
|
||||
"strsim 0.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b4be9c4c4b1f30b78d8a750e0822b6a6102d97e62061c583a6c1dea2dfb33ae"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.8"
|
||||
@ -494,6 +503,16 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "clap_mangen"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f17415fd4dfbea46e3274fcd8d368284519b358654772afb700dc2e8d2b24eeb"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"roff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color-eyre"
|
||||
version = "0.6.3"
|
||||
@ -1610,6 +1629,8 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_mangen",
|
||||
"color-eyre",
|
||||
"ctrlc",
|
||||
"dirs",
|
||||
@ -2576,6 +2597,12 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roff"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3"
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.8.1"
|
||||
|
@ -162,3 +162,9 @@ zbus = { version = "3.15.2", default-features = false, features = ["tokio"], opt
|
||||
|
||||
# schema
|
||||
schemars = { version = "0.8.21", optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
clap = { version = "4.5.9", features = ["derive"] }
|
||||
clap_complete = "4.5.2"
|
||||
clap_mangen = "0.2.20"
|
||||
serde = { version = "1.0.204", features = ["derive"] }
|
||||
|
69
build.rs
Normal file
69
build.rs
Normal file
@ -0,0 +1,69 @@
|
||||
#[path = "src/cli.rs"]
|
||||
mod cli;
|
||||
|
||||
use clap::Command;
|
||||
use clap::CommandFactory;
|
||||
use clap_complete::generate_to;
|
||||
use clap_complete::Shell::{Bash, Fish, Zsh};
|
||||
use clap_mangen::Man;
|
||||
use cli::Args;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
static NAME: &str = "ironbar";
|
||||
|
||||
fn generate_man_pages(cmd: Command) {
|
||||
let man_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("target/man");
|
||||
let mut buffer = Vec::default();
|
||||
|
||||
Man::new(cmd.clone()).render(&mut buffer).unwrap();
|
||||
fs::create_dir_all(&man_dir).unwrap();
|
||||
fs::write(man_dir.join(NAME.to_owned() + ".1"), buffer).unwrap();
|
||||
|
||||
for subcommand in cmd.get_subcommands() {
|
||||
let mut buffer = Vec::default();
|
||||
|
||||
Man::new(subcommand.clone()).render(&mut buffer).unwrap();
|
||||
fs::write(
|
||||
man_dir.join(NAME.to_owned() + "-" + subcommand.get_name() + ".1"),
|
||||
buffer,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
for subsubcommand in subcommand.get_subcommands() {
|
||||
let mut buffer = Vec::default();
|
||||
|
||||
Man::new(subsubcommand.clone()).render(&mut buffer).unwrap();
|
||||
fs::write(
|
||||
man_dir.join(
|
||||
NAME.to_owned()
|
||||
+ "-"
|
||||
+ subcommand.get_name()
|
||||
+ "-"
|
||||
+ subsubcommand.get_name()
|
||||
+ ".1",
|
||||
),
|
||||
buffer,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_shell_completions(mut cmd: Command) {
|
||||
let comp_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("target/completions");
|
||||
|
||||
fs::create_dir_all(&comp_dir).unwrap();
|
||||
|
||||
for shell in [Bash, Fish, Zsh] {
|
||||
generate_to(shell, &mut cmd, NAME, &comp_dir).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut cmd = Args::command();
|
||||
cmd.set_bin_name(NAME);
|
||||
|
||||
generate_man_pages(cmd.clone());
|
||||
generate_shell_completions(cmd);
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
luajit,
|
||||
luajitPackages,
|
||||
pkg-config,
|
||||
installShellFiles,
|
||||
hicolor-icon-theme,
|
||||
rustPlatform,
|
||||
lib,
|
||||
@ -41,6 +42,7 @@
|
||||
pkg-config
|
||||
wrapGAppsHook
|
||||
gobject-introspection
|
||||
installShellFiles
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
@ -83,6 +85,15 @@
|
||||
)
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
installManPage target/man/*
|
||||
|
||||
installShellCompletion --cmd ironbar \
|
||||
--bash target/completions/ironbar.bash \
|
||||
--fish target/completions/ironbar.fish \
|
||||
--zsh target/completions/_ironbar
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
updateScript = gnome.updateScript {
|
||||
packageName = pname;
|
||||
|
155
src/cli.rs
155
src/cli.rs
@ -1,9 +1,134 @@
|
||||
use crate::error::ExitCode;
|
||||
use crate::ipc::commands::Command;
|
||||
use crate::ipc::responses::Response;
|
||||
use clap::{Parser, ValueEnum};
|
||||
use clap::ArgAction;
|
||||
use clap::{Args as ClapArgs, Parser, Subcommand, ValueEnum};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::process::exit;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Subcommand, Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "command", rename_all = "snake_case")]
|
||||
pub enum Command {
|
||||
/// Pong
|
||||
Ping,
|
||||
|
||||
/// Open the GTK inspector.
|
||||
Inspect,
|
||||
|
||||
/// Reload the config.
|
||||
Reload,
|
||||
|
||||
/// Load an additional CSS stylesheet.
|
||||
/// The sheet is automatically hot-reloaded.
|
||||
LoadCss {
|
||||
/// The path to the sheet.
|
||||
path: PathBuf,
|
||||
},
|
||||
|
||||
/// Get and set reactive Ironvar values.
|
||||
#[command(subcommand)]
|
||||
Var(IronvarCommand),
|
||||
|
||||
/// Interact with a specific bar.
|
||||
Bar(BarCommand),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "subcommand", rename_all = "snake_case")]
|
||||
pub enum IronvarCommand {
|
||||
/// Set an `ironvar` value.
|
||||
/// This creates it if it does not already exist, and updates it if it does.
|
||||
/// Any references to this variable are automatically and immediately updated.
|
||||
/// Keys and values can be any valid UTF-8 string.
|
||||
Set {
|
||||
/// Variable key. Can be any alphanumeric ASCII string.
|
||||
key: Box<str>,
|
||||
/// Variable value. Can be any valid UTF-8 string.
|
||||
value: String,
|
||||
},
|
||||
|
||||
/// Get the current value of an `ironvar`.
|
||||
Get {
|
||||
/// Variable key.
|
||||
key: Box<str>,
|
||||
},
|
||||
|
||||
/// Gets the current value of all `ironvar`s.
|
||||
List,
|
||||
}
|
||||
|
||||
#[derive(ClapArgs, Debug, Serialize, Deserialize)]
|
||||
pub struct BarCommand {
|
||||
/// The name of the bar.
|
||||
pub name: String,
|
||||
|
||||
#[command(subcommand)]
|
||||
#[serde(flatten)]
|
||||
pub subcommand: BarCommandType,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "subcommand", rename_all = "snake_case")]
|
||||
pub enum BarCommandType {
|
||||
// == Visibility == \\
|
||||
/// Force the bar to be shown, regardless of current visibility state.
|
||||
Show,
|
||||
/// Force the bar to be hidden, regardless of current visibility state.
|
||||
Hide,
|
||||
/// Set the bar's visibility state via an argument.
|
||||
SetVisible {
|
||||
/// The new visibility state.
|
||||
#[clap(
|
||||
num_args(1),
|
||||
require_equals(true),
|
||||
action = ArgAction::Set,
|
||||
)]
|
||||
visible: bool,
|
||||
},
|
||||
/// Toggle the current visibility state between shown and hidden.
|
||||
ToggleVisible,
|
||||
/// Get the bar's visibility state.
|
||||
GetVisible,
|
||||
|
||||
// == Popup visibility == \\
|
||||
/// Open a popup, regardless of current state.
|
||||
/// If opening this popup, and a different popup on the same bar is already open, the other is closed.
|
||||
ShowPopup {
|
||||
/// The configured name of the widget.
|
||||
widget_name: String,
|
||||
},
|
||||
/// Close a popup, regardless of current state.
|
||||
HidePopup,
|
||||
/// Set the popup's visibility state via an argument.
|
||||
/// If opening this popup, and a different popup on the same bar is already open, the other is closed.
|
||||
SetPopupVisible {
|
||||
/// The configured name of the widget.
|
||||
widget_name: String,
|
||||
|
||||
#[clap(
|
||||
num_args(1),
|
||||
require_equals(true),
|
||||
action = ArgAction::Set,
|
||||
)]
|
||||
visible: bool,
|
||||
},
|
||||
/// Toggle a popup open/closed.
|
||||
/// If opening this popup, and a different popup on the same bar is already open, the other is closed.
|
||||
TogglePopup {
|
||||
/// The configured name of the widget.
|
||||
widget_name: String,
|
||||
},
|
||||
/// Get the popup's current visibility state.
|
||||
GetPopupVisible,
|
||||
|
||||
// == Exclusivity == \\
|
||||
/// Set whether the bar reserves an exclusive zone.
|
||||
SetExclusive {
|
||||
#[clap(
|
||||
num_args(1),
|
||||
require_equals(true),
|
||||
action = ArgAction::Set,
|
||||
)]
|
||||
exclusive: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Serialize, Deserialize)]
|
||||
#[command(version)]
|
||||
@ -38,23 +163,3 @@ pub enum Format {
|
||||
Plain,
|
||||
Json,
|
||||
}
|
||||
|
||||
pub fn handle_response(response: Response, format: Format) {
|
||||
let is_err = matches!(response, Response::Err { .. });
|
||||
|
||||
match format {
|
||||
Format::Plain => match response {
|
||||
Response::Ok => println!("ok"),
|
||||
Response::OkValue { value } => println!("{value}"),
|
||||
Response::Err { message } => eprintln!("error\n{}", message.unwrap_or_default()),
|
||||
},
|
||||
Format::Json => println!(
|
||||
"{}",
|
||||
serde_json::to_string(&response).expect("to be valid json")
|
||||
),
|
||||
}
|
||||
|
||||
if is_err {
|
||||
exit(ExitCode::IpcResponseError as i32)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::Ipc;
|
||||
use crate::ipc::{Command, Response};
|
||||
use crate::cli::Command;
|
||||
use crate::ipc::Response;
|
||||
use color_eyre::Result;
|
||||
use color_eyre::{Help, Report};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
27
src/main.rs
27
src/main.rs
@ -28,11 +28,15 @@ use tracing::{debug, error, info, warn};
|
||||
use universal_config::ConfigLoader;
|
||||
|
||||
use crate::bar::{create_bar, Bar};
|
||||
#[cfg(feature = "cli")]
|
||||
use crate::cli::Format;
|
||||
use crate::clients::wayland::OutputEventType;
|
||||
use crate::clients::Clients;
|
||||
use crate::config::{Config, MonitorConfig};
|
||||
use crate::error::ExitCode;
|
||||
#[cfg(feature = "ipc")]
|
||||
use crate::ipc::responses::Response;
|
||||
#[cfg(feature = "ipc")]
|
||||
use crate::ironvar::VariableManager;
|
||||
use crate::style::load_css;
|
||||
|
||||
@ -98,7 +102,7 @@ fn run_with_args() {
|
||||
eprintln!("RESPONSE: {res:?}")
|
||||
}
|
||||
|
||||
cli::handle_response(res, args.format.unwrap_or_default())
|
||||
handle_response(res, args.format.unwrap_or_default())
|
||||
}
|
||||
Err(err) => error!("{err:?}"),
|
||||
};
|
||||
@ -108,6 +112,27 @@ fn run_with_args() {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
pub fn handle_response(response: Response, format: Format) {
|
||||
let is_err = matches!(response, Response::Err { .. });
|
||||
|
||||
match format {
|
||||
Format::Plain => match response {
|
||||
Response::Ok => println!("ok"),
|
||||
Response::OkValue { value } => println!("{value}"),
|
||||
Response::Err { message } => eprintln!("error\n{}", message.unwrap_or_default()),
|
||||
},
|
||||
Format::Json => println!(
|
||||
"{}",
|
||||
serde_json::to_string(&response).expect("to be valid json")
|
||||
),
|
||||
}
|
||||
|
||||
if is_err {
|
||||
exit(ExitCode::IpcResponseError as i32)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Ironbar {
|
||||
bars: Rc<RefCell<Vec<Bar>>>,
|
||||
|
Loading…
Reference in New Issue
Block a user