Added installation to nix flake as well as home manager module

This commit is contained in:
Javier Feliz 2025-09-07 19:39:19 -04:00
parent d3eaa24e70
commit f8aac06893
5 changed files with 205 additions and 49 deletions

View File

@ -61,6 +61,48 @@ Waycast aims to be:
- **Extensible** - Plugin system for custom functionality - **Extensible** - Plugin system for custom functionality
- **Native** - Proper Wayland integration, not an Electron app - **Native** - Proper Wayland integration, not an Electron app
## Installation
### Nix Flakes
Add to your `flake.nix` inputs:
```nix
waycast.url = "git+https://gitgud.foo/thegrind/waycast";
```
**Install as package:**
```nix
environment.systemPackages = [ inputs.waycast.packages.${system}.default ];
# or for home-manager:
home.packages = [ inputs.waycast.packages.${system}.default ];
```
**With Home Manager module (recommended):**
```nix
imports = [ inputs.waycast.homeManagerModules.default ];
programs.waycast = {
enable = true;
config = {
plugins.projects = {
search_paths = ["/absolute/path/to/search"];
skip_dirs = [ "node_modules" "target" ".git" ];
open_command = "code -n {path}";
};
plugins.file_search = {
search_paths = ["/absolute/path/to/search"];
ignore_dirs = ["scripts", "temp"]; # Just directory names here
};
};
css = ''
window {
background: rgba(0, 0, 0, 0.8);
border-radius: 12px;
}
'';
};
```
## Contributing ## Contributing
TBA TBA

View File

@ -6,12 +6,66 @@
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { self, nixpkgs, flake-utils }: outputs =
flake-utils.lib.eachDefaultSystem (system: {
self,
nixpkgs,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (
system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
in in
{ {
packages.default = pkgs.rustPlatform.buildRustPackage {
pname = "waycast";
version = "0.0.1";
src = self;
cargoLock.lockFile = ./Cargo.lock;
doCheck = true;
cargoTestFlags = [
"--bins"
"--tests"
];
nativeBuildInputs = with pkgs; [
pkg-config
makeWrapper
];
buildInputs = with pkgs; [
# GTK4 stack
gtk4
glib
gdk-pixbuf
pango
cairo
harfbuzz
librsvg
# Wayland + layer shell (GTK4 variant)
wayland
gtk4-layer-shell
];
# Wrap binary to ensure icon themes are available
postInstall = ''
wrapProgram $out/bin/waycast \
--prefix XDG_DATA_DIRS : "${pkgs.hicolor-icon-theme}/share:${pkgs.adwaita-icon-theme}/share"
'';
meta = with pkgs.lib; {
description = "GTK4-based application launcher for Wayland compositors";
homepage = "https://gitgud.foo/thegrind/waycast";
license = licenses.mit;
maintainers = [ "Javier Feliz" ];
platforms = platforms.linux;
};
};
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
# Build tools # Build tools
@ -35,5 +89,18 @@
adwaita-icon-theme adwaita-icon-theme
]; ];
}; };
});
homeManagerModules.waycast =
{
config,
lib,
pkgs,
...
}:
{
imports = [ ./modules/home-manager/waycast.nix ];
programs.waycast.package = self.packages.${system}.default;
};
}
);
} }

View File

@ -0,0 +1,89 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.programs.waycast;
# Convert a Nix attribute set to TOML format
toToml = value: pkgs.formats.toml { }.generate "waycast.toml" value;
in
{
options.programs.waycast = {
enable = mkEnableOption "waycast application launcher";
package = mkOption {
type = types.package;
default = pkgs.waycast or (throw "waycast package not found in pkgs");
description = "The waycast package to use";
};
settings = mkOption {
type = types.attrs;
default = { };
example = literalExpression ''
{
plugins = {
projects = {
search_paths = [ "~/code" "~/projects" ];
skip_dirs = [ "node_modules" "target" ".git" ];
open_command = "code -n {path}";
};
file_search = {
search_paths = [ "~/Documents" "~/Downloads" ];
ignore_dirs = [ "cache" "vendor" ];
};
};
}
'';
description = ''
Waycast configuration. This will be converted to TOML format
and placed in ~/.config/waycast/waycast.toml
'';
};
css = mkOption {
type = types.nullOr types.lines;
default = null;
example = ''
window {
background: rgba(0, 0, 0, 0.8);
border-radius: 12px;
}
.search-entry {
font-size: 16px;
padding: 12px;
}
'';
description = ''
Custom GTK CSS styling for waycast.
This will be placed in ~/.config/waycast/waycast.css
'';
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
xdg.configFile = mkMerge [
(mkIf (cfg.config != { }) {
"waycast/waycast.toml".source = toToml cfg.config;
})
(mkIf (cfg.css != null) {
"waycast/waycast.css".text = cfg.css;
})
];
# Ensure cache and data dirs exist to avoid runtime errors in the future
home.file."${config.xdg.cacheHome}/waycast".isDir = true;
home.file."${config.xdg.dataHome}/waycast".isDir = true;
};
}

View File

@ -1,42 +0,0 @@
use std::collections::HashMap;
use config::Config;
use directories::ProjectDirs;
pub fn main() {
// if let Some(dirs) = ProjectDirs::from("dev.thegrind", "The Grind", "waycast") {
// let config_dir = dirs.config_dir();
// let cache_dir = dirs.cache_dir();
// let data_dir = dirs.data_dir();
// println!("Config: {}", config_dir.display());
// println!("Cache: {}", cache_dir.display());
// println!("Data: {}", data_dir.display());
// }
// let settings = Config::builder()
// .add_source(config::File::with_name("waycast.toml"))
// .add_source(config::Environment::with_prefix("WAYCAST"))
// .build()
// .unwrap();
println!(
"{:?}",
waycast_config::config_file()
.get::<String>("plugins.projects.open_command")
.expect("Could not deserialize")
);
// // Start with defaults
// let mut config = WaycastConfig::default();
// config.plugins.file_search.ignore_dirs =
// vec!["vendor".into(), "pycache".into(), "node_modules".into()];
// // Serialize to TOML
// let toml_str = toml::to_string_pretty(&config).expect("Failed");
// println!("Serialized TOML:\n{}", toml_str);
// // Deserialize back
// let parsed: WaycastConfig = toml::from_str(&toml_str).expect("Fuck");
// println!("Deserialized struct:\n{:#?}", parsed);
}

View File

@ -50,7 +50,7 @@ pub fn get() -> &'static Cache {
// Get an existing cache at the given path or // Get an existing cache at the given path or
// create it if it doesn't exist // create it if it doesn't exist
fn new<P: AsRef<Path>>(db_path: P) -> Result<Cache, CacheError> { pub fn new<P: AsRef<Path>>(db_path: P) -> Result<Cache, CacheError> {
let db = Database::create(db_path)?; let db = Database::create(db_path)?;
// Initialize the table if it doesn't exist // Initialize the table if it doesn't exist
@ -224,7 +224,7 @@ mod tests {
#[test] #[test]
fn test_cache_remember() { fn test_cache_remember() {
let temp_file = NamedTempFile::new().unwrap(); let temp_file = NamedTempFile::new().unwrap();
let cache = Cache::new(temp_file.path()).unwrap(); let cache = new(temp_file.path()).unwrap();
let result = cache let result = cache
.remember("test_key", || "computed_value".to_string()) .remember("test_key", || "computed_value".to_string())
@ -241,7 +241,7 @@ mod tests {
#[test] #[test]
fn test_cache_ttl() { fn test_cache_ttl() {
let temp_file = NamedTempFile::new().unwrap(); let temp_file = NamedTempFile::new().unwrap();
let cache = Cache::new(temp_file.path()).unwrap(); let cache = new(temp_file.path()).unwrap();
// Cache with very short TTL // Cache with very short TTL
let result = cache let result = cache