From 6ee8b07d06f9d9914497b1606b2833f60d0f6ab6 Mon Sep 17 00:00:00 2001 From: i0uring Date: Sun, 14 Sep 2025 12:16:34 +0200 Subject: [PATCH] :sparkles: add flake.nix --- .gitignore | 1 + flake.lock | 113 ++++++++++++++++++++ flake.nix | 38 +++++++ src/app.rs | 292 ++++++++++++++++++++++++++-------------------------- src/main.rs | 35 +++---- 5 files changed, 315 insertions(+), 164 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitignore b/.gitignore index 540d72e..a80f68f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target/ .idea/ Cargo.lock +flake.lock diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5af69f5 --- /dev/null +++ b/flake.lock @@ -0,0 +1,113 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "flake": false, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1757487488, + "narHash": "sha256-zwE/e7CuPJUWKdvvTCB7iunV4E/+G0lKfv4kk/5Izdg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ab0f3607a6c7486ea22229b92ed2d355f1482ee0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs", + "rustup": "rustup" + } + }, + "rustup": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1757730403, + "narHash": "sha256-Jxl4OZRVsXs8JxEHUVQn3oPu6zcqFyGGKaFrlNgbzp0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "3232f7f8bd07849fc6f4ae77fe695e0abb2eba2c", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..2a37581 --- /dev/null +++ b/flake.nix @@ -0,0 +1,38 @@ +{ + description = "cutie flake ~"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + gitignore = { url = "github:hercules-ci/gitignore.nix"; flake = false; }; + flake-utils.url = "github:numtide/flake-utils"; + rustup.url = "github:oxalica/rust-overlay"; + }; + + outputs = inputs@{ self, nixpkgs, flake-utils, rustup, ... }: + flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: let + overlays = [ (import rustup) ]; + pkgs = import nixpkgs { inherit system overlays; }; + libPath = with pkgs; lib.makeLibraryPath [ + libGL libxkbcommon + wayland wayland-utils + musl musl-fts musl-obstack + makeWrapper pkg-config gcc + libiconv libtool autoconf automake + ]; + gitignoreSrc = pkgs.callPackage inputs.gitignore { }; + in rec { + packages.hello = pkgs.callPackage ./default.nix { inherit gitignoreSrc; }; + legacyPackages = packages; + defaultPackage = packages.hello; + devShell = pkgs.mkShell { + CARGO_INSTALL_ROOT = "${toString ./.}/.cargo"; + + RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}"; + LD_LIBRARY_PATH = libPath; + + buildInputs = with pkgs; [ (rust-bin.selectLatestNightlyWith (toolchain: toolchain.complete.override { + targets = [ "x86_64-unknown-linux-musl" "wasm32-unknown-unknown" ]; + })) ]; + }; + }); +} diff --git a/src/app.rs b/src/app.rs index 4fd637b..1dde9e0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -8,165 +8,165 @@ use std::fs; #[derive(serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct CatnipApp { - label: String, - #[serde(skip)] - editor_theme: ColorTheme, - #[serde(skip)] - editor_syntax: Syntax, - editor_text: String, - #[serde(skip)] - value: f32, + label: String, + #[serde(skip)] + editor_theme: ColorTheme, + #[serde(skip)] + editor_syntax: Syntax, + editor_text: String, + #[serde(skip)] + value: f32, } impl Default for CatnipApp { - fn default() -> Self { - Self { - label: "println!(\"meow\");".to_owned(), - editor_theme: ColorTheme::default(), - editor_syntax: Syntax::default(), - editor_text: "".to_owned(), - value: 2.7, - } + fn default() -> Self { + Self { + label: "println!(\"meow\");".to_owned(), + editor_theme: ColorTheme::default(), + editor_syntax: Syntax::default(), + editor_text: "".to_owned(), + value: 2.7, } + } } impl CatnipApp { - pub fn new(cc: &eframe::CreationContext<'_>) -> Self { - if let Some(storage) = cc.storage { - return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); - } - Default::default() + pub fn new(cc: &eframe::CreationContext<'_>) -> Self { + if let Some(storage) = cc.storage { + return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); } + Default::default() + } } impl eframe::App for CatnipApp { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - let modal = Modal::new(ctx, "open folder modal :3"); - modal.show(|ui| { - modal.title(ui, "Hello world!"); - modal.frame(ui, |ui| { - modal.body(ui, "This is a modal."); - }); - modal.buttons(ui, |ui| { - if modal.button(ui, "meow").clicked() {}; - if modal.button(ui, "close").clicked() {}; - }); - }); + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + let modal = Modal::new(ctx, "open folder modal :3"); + modal.show(|ui| { + modal.title(ui, "Hello world!"); + modal.frame(ui, |ui| { + modal.body(ui, "This is a modal."); + }); + modal.buttons(ui, |ui| { + if modal.button(ui, "meow").clicked() {}; + if modal.button(ui, "close").clicked() {}; + }); + }); - // top bar - egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { - egui::menu::bar(ui, |ui| { - ui.menu_button("File", |ui| { - ui.menu_button("New …", |_| {}); - ui.menu_button("Open …", |ui| { - if ui.button("File").clicked() - && let Some(path) = rfd::FileDialog::new().pick_file() - { - self.editor_text = - fs::read_to_string(path.display().to_string()).unwrap(); - ui.close_kind(UiKind::Menu) - } - if ui.button("Folder").clicked() && !modal.is_open() { - modal.open(); - ui.close_kind(UiKind::Menu) - } - }); - if ui.button("Quit").clicked() { - ctx.send_viewport_cmd(egui::ViewportCommand::Close); - } + // top bar + egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { + egui::menu::bar(ui, |ui| { + ui.menu_button("File", |ui| { + ui.menu_button("New …", |_| {}); + ui.menu_button("Open …", |ui| { + if ui.button("File").clicked() + && let Some(path) = rfd::FileDialog::new().pick_file() + { + self.editor_text = + fs::read_to_string(path.display().to_string()).unwrap(); + ui.close_kind(UiKind::Menu) + } + if ui.button("Folder").clicked() && !modal.is_open() { + modal.open(); + ui.close_kind(UiKind::Menu) + } + }); + if ui.button("Quit").clicked() { + ctx.send_viewport_cmd(egui::ViewportCommand::Close); + } + }); + }); + }); + + // main content + egui::CentralPanel::default().show(ctx, |ui| { + ui.with_layout(egui::Layout::left_to_right(Align::Max), |ui| { + CodeEditor::default() + .id_source("cat editor :3") + .with_fontsize(12.0) + .with_theme(self.editor_theme) + .with_syntax(self.editor_syntax.clone()) + .with_numlines(true) + .vscroll(true) + .stick_to_bottom(true) + .show(ui, &mut self.editor_text); + }); + + // header example: + // ui.heading("eframe template"); + + /* config examples with serde: + ui.horizontal(|ui| { + ui.label("Write something: "); + ui.te xt_edit_singleline(&mut self.label); + }); + + ui.add(egui::Slider::new(&mut self.value, 0.0..=10.0).text("value")); + */ + }); + + // bottom bar + egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| { + ui.horizontal(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.label("made by "); + ui.hyperlink_to("lunarydess", "https://github.com/lunarydess"); + ui.label(" with ♡"); + + ui.with_layout(egui::Layout::right_to_left(Align::Center), |ui| { + ui.menu_image_button(egui::include_image!("cogwheel.svg"), |ui| { + // syntax selector + egui::ComboBox::from_label("Syntax") + .wrap_mode(TextWrapMode::Wrap) + .selected_text(format!("{:?}", &self.editor_syntax.language)) + .show_ui(ui, |ui| { + [ + Syntax::asm(), + Syntax::shell(), + Syntax::sql(), + Syntax::lua(), + Syntax::rust(), + Syntax::python(), + Syntax::java(), + ] + .iter() + .for_each(|syntax| { + ui.selectable_value( + &mut self.editor_syntax, + syntax.clone(), + syntax.language, + ); + }); + }); + + // theme selector + let mut theme = ui.ctx().options(|opt| opt.theme_preference); + egui::ComboBox::from_label("Theme") + .wrap_mode(TextWrapMode::Wrap) + .selected_text(format!("{:?}", theme)) + .show_ui(ui, |ui| { + ui.selectable_value(&mut theme, ThemePreference::System, "💻 System"); + ui.selectable_value(&mut theme, ThemePreference::Light, "☀ Light"); + ui.selectable_value(&mut theme, ThemePreference::Dark, "🌙 Dark"); + }); + ui.ctx().set_theme(theme); + + // scheme selector + egui::ComboBox::from_label("Scheme") + .wrap_mode(TextWrapMode::Wrap) + .selected_text(format!("{:?}", &self.editor_theme.name)) + .show_ui(ui, |ui| { + DEFAULT_THEMES.iter().clone().for_each(|theme| { + ui.selectable_value(&mut self.editor_theme, *theme, theme.name); }); - }); + }); + }); }); + }); + }); + } - // main content - egui::CentralPanel::default().show(ctx, |ui| { - ui.with_layout(egui::Layout::left_to_right(Align::Max), |ui| { - CodeEditor::default() - .id_source("cat editor :3") - .with_fontsize(12.0) - .with_theme(self.editor_theme) - .with_syntax(self.editor_syntax.clone()) - .with_numlines(true) - .vscroll(true) - .stick_to_bottom(true) - .show(ui, &mut self.editor_text); - }); - - // header example: - // ui.heading("eframe template"); - - /* config examples with serde: - ui.horizontal(|ui| { - ui.label("Write something: "); - ui.te xt_edit_singleline(&mut self.label); - }); - - ui.add(egui::Slider::new(&mut self.value, 0.0..=10.0).text("value")); - */ - }); - - // bottom bar - egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| { - ui.horizontal(|ui| { - ui.spacing_mut().item_spacing.x = 0.0; - ui.label("made by "); - ui.hyperlink_to("lunarydess", "https://github.com/lunarydess"); - ui.label(" with ♡"); - - ui.with_layout(egui::Layout::right_to_left(Align::Center), |ui| { - ui.menu_image_button(egui::include_image!("cogwheel.svg"), |ui| { - // syntax selector - egui::ComboBox::from_label("Syntax") - .wrap_mode(TextWrapMode::Wrap) - .selected_text(format!("{:?}", &self.editor_syntax.language)) - .show_ui(ui, |ui| { - [ - Syntax::asm(), - Syntax::shell(), - Syntax::sql(), - Syntax::lua(), - Syntax::rust(), - Syntax::python(), - Syntax::java(), - ] - .iter() - .for_each(|syntax| { - ui.selectable_value( - &mut self.editor_syntax, - syntax.clone(), - syntax.language, - ); - }); - }); - - // theme selector - let mut theme = ui.ctx().options(|opt| opt.theme_preference); - egui::ComboBox::from_label("Theme") - .wrap_mode(TextWrapMode::Wrap) - .selected_text(format!("{:?}", theme)) - .show_ui(ui, |ui| { - ui.selectable_value(&mut theme, ThemePreference::System, "💻 System", ); - ui.selectable_value(&mut theme, ThemePreference::Light, "☀ Light"); - ui.selectable_value(&mut theme, ThemePreference::Dark, "🌙 Dark"); - }); - ui.ctx().set_theme(theme); - - // scheme selector - egui::ComboBox::from_label("Scheme") - .wrap_mode(TextWrapMode::Wrap) - .selected_text(format!("{:?}", &self.editor_theme.name)) - .show_ui(ui, |ui| { - DEFAULT_THEMES.iter().clone().for_each(|theme| { - ui.selectable_value(&mut self.editor_theme, *theme, theme.name); - }); - }); - }); - }); - }); - }); - } - - fn save(&mut self, storage: &mut dyn eframe::Storage) { - eframe::set_value(storage, eframe::APP_KEY, self); - } + fn save(&mut self, storage: &mut dyn eframe::Storage) { + eframe::set_value(storage, eframe::APP_KEY, self); + } } diff --git a/src/main.rs b/src/main.rs index 3622c3c..fb16e9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,21 @@ use application_catnip::CatnipApp; -use eframe::Renderer; +use eframe::{wgpu, Renderer}; fn main() { - env_logger::init(); - eframe::run_native( - "Catnip Editor", - eframe::NativeOptions { - centered: true, - renderer: Renderer::Wgpu, - viewport: egui::ViewportBuilder::default() - .with_inner_size([400.0, 300.0]) - .with_min_inner_size([300.0, 220.0]), - ..Default::default() - }, - Box::new(|context| { - egui_extras::install_image_loaders(&context.egui_ctx); - Ok(Box::::default()) - }), - ) - .expect("TODO: panic message"); + env_logger::init(); + eframe::run_native( + "Catnip Editor", + eframe::NativeOptions { + centered: true, + renderer: Renderer::Glow, + viewport: egui::ViewportBuilder::default() + .with_inner_size([400.0, 300.0]) + .with_min_inner_size([300.0, 220.0]), + ..Default::default() + }, + Box::new(|context| { + egui_extras::install_image_loaders(&context.egui_ctx); + Ok(Box::::default()) + }), + ).expect("TODO: panic message"); }