aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Jankowski <daniel.jankowski@rub.de>2023-08-30 19:37:49 +0200
committerDaniel Jankowski <daniel.jankowski@rub.de>2023-08-30 19:37:49 +0200
commit8257d1778249f50efba08effed5a88b663d9fa4e (patch)
tree11ca4d162c62ac42d4aa4d55d51b29a4b67f646b /src
downloadsl0pstatus-8257d1778249f50efba08effed5a88b663d9fa4e.tar.gz
sl0pstatus-8257d1778249f50efba08effed5a88b663d9fa4e.tar.xz
sl0pstatus-8257d1778249f50efba08effed5a88b663d9fa4e.zip
feat: initial commit
Diffstat (limited to 'src')
-rw-r--r--src/config.rs104
-rw-r--r--src/main.rs100
2 files changed, 204 insertions, 0 deletions
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..2529bf1
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,104 @@
+use std::collections::BTreeMap;
+
+#[derive(Default)]
+pub struct ModuleConfig {
+ pub enabled_modules: Vec<String>,
+ pub formatted_parts: Vec<FormattedPart>,
+}
+
+pub struct FormattedPart {
+ pub order: u8,
+ pub fg: u8,
+ pub bg: u8,
+ pub bold: bool,
+ pub italic: bool,
+ pub content: String,
+}
+
+impl FormattedPart {
+ pub fn from_format_string(format: String) -> Self {
+ let mut result = FormattedPart::default();
+
+ let format_content_split = format.split("]");
+
+ if format_content_split.clone().count() == 1 {
+ result.content = format;
+
+ return result;
+ }
+
+ let format_content_split = format_content_split.collect::<Vec<&str>>();
+ result.content = format_content_split[1].to_string();
+
+ let parts = format_content_split[0].split(",");
+ for part in parts {
+ if part.starts_with("fg=") {
+ // TODO: better error handling
+ result.fg = part
+ .strip_prefix("fg=")
+ .unwrap()
+ .to_string()
+ .parse::<u8>()
+ .unwrap();
+ }
+
+ if part.starts_with("bg=") {
+ // TODO: better error handling
+ result.bg = part
+ .strip_prefix("bg=")
+ .unwrap()
+ .to_string()
+ .parse::<u8>()
+ .unwrap();
+ }
+
+ result.bold = part.eq("bold");
+ result.italic = part.eq("italic");
+ }
+
+ result
+ }
+}
+
+impl Default for FormattedPart {
+ fn default() -> Self {
+ Self {
+ order: 0,
+ fg: 255,
+ bg: 0,
+ bold: false,
+ italic: false,
+ content: "".to_string(),
+ }
+ }
+}
+
+pub fn parse_format(config: BTreeMap<String, String>) -> ModuleConfig {
+ let format = config.get("format");
+ let mut formatted_parts = Vec::new();
+
+ if format.is_none() {
+ return ModuleConfig {
+ enabled_modules: Vec::new(),
+ formatted_parts,
+ };
+ }
+
+ let format = format.unwrap();
+
+ let mut counter: u8 = 0;
+ let color_parts = format.split("#[");
+ for color_part in color_parts {
+ let mut part = FormattedPart::from_format_string(color_part.to_string());
+ part.order = counter.clone();
+
+ formatted_parts.push(part);
+
+ counter += 1;
+ }
+
+ ModuleConfig {
+ enabled_modules: Vec::new(),
+ formatted_parts,
+ }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..e4e3f30
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,100 @@
+use ansi_term::{Colour::Fixed, Style};
+use zellij_tile::prelude::*;
+
+use std::{
+ collections::{BTreeMap, HashMap},
+ u8,
+};
+
+mod config;
+
+#[derive(Default)]
+struct State {
+ mode_log: HashMap<String, usize>,
+ tabs: Vec<String>,
+ userspace_configuration: BTreeMap<String, String>,
+ module_config: config::ModuleConfig,
+}
+
+register_plugin!(State);
+
+impl ZellijPlugin for State {
+ fn load(&mut self, configuration: BTreeMap<String, String>) {
+ self.userspace_configuration = configuration.clone();
+ // we need the ReadApplicationState permission to receive the ModeUpdate and TabUpdate
+ // events
+ // we need the RunCommands permission to run "cargo test" in a floating window
+ request_permission(&[
+ PermissionType::ReadApplicationState,
+ PermissionType::RunCommands,
+ ]);
+ subscribe(&[EventType::ModeUpdate, EventType::TabUpdate, EventType::Key]);
+
+ self.module_config = config::parse_format(configuration);
+
+ // TODO: current mode
+ }
+
+ fn update(&mut self, event: Event) -> bool {
+ let mut should_render = false;
+ match event {
+ Event::ModeUpdate(mode_info) => {
+ let mode = format!("{:?}", mode_info.mode);
+ let count = self.mode_log.entry(mode).or_insert(0);
+ *count += 1;
+ should_render = true;
+ }
+ Event::TabUpdate(tab_info) => {
+ self.tabs = tab_info.iter().map(|t| t.name.clone()).collect();
+ should_render = true;
+ }
+ _ => (),
+ };
+ should_render
+ }
+
+ fn render(&mut self, rows: usize, cols: usize) {
+ // TODO: render blocks in correct order and print them
+
+ let colored_rows = color(CYAN, &rows.to_string());
+ let colored_cols = color_bold(CYAN, &cols.to_string());
+ println!("");
+ println!("I have {} rows and {} columns", colored_rows, colored_cols);
+ println!("");
+ println!(
+ "{} {:#?}",
+ color_bold(
+ GREEN,
+ "I was started with the following user configuration:"
+ ),
+ self.userspace_configuration
+ );
+ println!("");
+ println!("{}", color_bold(GREEN, "Modes:"));
+ for (mode, count) in &self.mode_log {
+ let count = color_bold(ORANGE, &count.to_string());
+ println!("{} -> Changed {} times", mode, count);
+ }
+ println!("");
+ let current_tabs = color_bold(GREEN, "Current Tabs:");
+ let comma = color_bold(ORANGE, ", ");
+ println!("{} {}", current_tabs, self.tabs.join(&comma));
+ }
+}
+
+pub const CYAN: u8 = 51;
+pub const GRAY_LIGHT: u8 = 238;
+pub const GRAY_DARK: u8 = 245;
+pub const WHITE: u8 = 15;
+pub const BLACK: u8 = 16;
+pub const RED: u8 = 124;
+pub const GREEN: u8 = 154;
+pub const ORANGE: u8 = 166;
+
+fn color(color: u8, text: &str) -> String {
+ format!("{}", Style::new().fg(Fixed(color)).paint(text))
+}
+
+fn color_bold(color: u8, text: &str) -> String {
+ format!("{}", Style::new().fg(Fixed(color)).bold().paint(text))
+}