-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
vicinae service: init #8093
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vicinae service: init #8093
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { pkgs, ... }: | ||
| { | ||
| time = "2025-11-04T02:33:15+00:00"; | ||
| condition = pkgs.stdenv.hostPlatform.isLinux; | ||
| message = '' | ||
| A new program is available: 'programs.vicinae'. | ||
|
|
||
| Vicinae is a modern application launcher daemon for Linux with support for | ||
| extensions, custom themes, and layer shell integration. | ||
|
|
||
| The module provides: | ||
| - Systemd service integration with automatic start support | ||
| - Extension management with helpers for Vicinae and Raycast extensions | ||
| - Theme configuration support | ||
| - Declarative settings via 'programs.vicinae.settings' | ||
| - Layer shell integration for Wayland compositors | ||
|
|
||
| See the module options for more details on configuration. | ||
| ''; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,244 @@ | ||
| { | ||
| config, | ||
| pkgs, | ||
| lib, | ||
| ... | ||
| }: | ||
| let | ||
| cfg = config.programs.vicinae; | ||
|
|
||
| jsonFormat = pkgs.formats.json { }; | ||
| in | ||
| { | ||
| meta.maintainers = [ lib.maintainers.leiserfg ]; | ||
|
|
||
| options.programs.vicinae = { | ||
| enable = lib.mkEnableOption "vicinae launcher daemon"; | ||
|
|
||
| package = lib.mkPackageOption pkgs "vicinae" { nullable = true; }; | ||
|
|
||
| systemd = { | ||
| enable = lib.mkEnableOption "vicinae systemd integration"; | ||
|
|
||
| autoStart = lib.mkOption { | ||
| type = lib.types.bool; | ||
| default = true; | ||
| description = "If the vicinae daemon should be started automatically"; | ||
| }; | ||
|
|
||
| target = lib.mkOption { | ||
| type = lib.types.str; | ||
| default = "graphical-session.target"; | ||
| example = "sway-session.target"; | ||
| description = '' | ||
| The systemd target that will automatically start the vicinae service. | ||
| ''; | ||
| }; | ||
| }; | ||
|
|
||
| useLayerShell = lib.mkOption { | ||
| type = lib.types.bool; | ||
| default = true; | ||
| description = "If vicinae should use the layer shell"; | ||
| }; | ||
|
|
||
| extensions = lib.mkOption { | ||
| type = lib.types.listOf lib.types.package; | ||
| default = [ ]; | ||
| description = '' | ||
| List of Vicinae extensions to install. | ||
|
leiserfg marked this conversation as resolved.
|
||
|
|
||
| You can use the `config.lib.vicinae.mkExtension` and `config.lib.vicinae.mkRayCastExtension` functions to create them, like: | ||
| ```nix | ||
| [ | ||
| (config.lib.vicinae.mkExtension { | ||
| name = "test-extension"; | ||
| src = | ||
| pkgs.fetchFromGitHub { | ||
| owner = "schromp"; | ||
| repo = "vicinae-extensions"; | ||
| rev = "f8be5c89393a336f773d679d22faf82d59631991"; | ||
| sha256 = "sha256-zk7WIJ19ITzRFnqGSMtX35SgPGq0Z+M+f7hJRbyQugw="; | ||
| } | ||
| + "/test-extension"; | ||
| }) | ||
| (config.lib.vicinae.mkRayCastExtension { | ||
| name = "gif-search"; | ||
| sha256 = "sha256-G7il8T1L+P/2mXWJsb68n4BCbVKcrrtK8GnBNxzt73Q="; | ||
| rev = "4d417c2dfd86a5b2bea202d4a7b48d8eb3dbaeb1"; | ||
| }) | ||
| ], | ||
| ``` | ||
| ''; | ||
| }; | ||
|
|
||
| themes = lib.mkOption { | ||
|
leiserfg marked this conversation as resolved.
|
||
| inherit (jsonFormat) type; | ||
| default = { }; | ||
| description = '' | ||
| Theme settings to add to the themes folder in `~/.config/vicinae/themes`. | ||
|
leiserfg marked this conversation as resolved.
|
||
|
|
||
| The attribute name of the theme will be the name of theme json file, | ||
| e.g. `base16-default-dark` will be `base16-default-dark.json`. | ||
| ''; | ||
| example = | ||
| lib.literalExpression # nix | ||
| '' | ||
| { | ||
| base16-default-dark = { | ||
| version = "1.0.0"; | ||
| appearance = "dark"; | ||
| icon = /path/to/icon.png; | ||
| name = "base16 default dark"; | ||
| description = "base16 default dark by Chris Kempson"; | ||
| palette = { | ||
| background = "#181818"; | ||
| foreground = "#d8d8d8"; | ||
| blue = "#7cafc2"; | ||
| green = "#a3be8c"; | ||
| magenta = "#ba8baf"; | ||
| orange = "#dc9656"; | ||
| purple = "#a16946"; | ||
| red = "#ab4642"; | ||
| yellow = "#f7ca88"; | ||
| cyan = "#86c1b9"; | ||
| }; | ||
| }; | ||
| } | ||
| ''; | ||
| }; | ||
|
|
||
| settings = lib.mkOption { | ||
| inherit (jsonFormat) type; | ||
| default = { }; | ||
| description = "Settings written as JSON to `~/.config/vicinae/vicinae.json."; | ||
| example = lib.literalExpression '' | ||
| { | ||
| faviconService = "twenty"; | ||
| font = { | ||
| size = 10; | ||
| }; | ||
| popToRootOnClose = false; | ||
| rootSearch = { | ||
| searchFiles = false; | ||
| }; | ||
| theme = { | ||
| name = "vicinae-dark"; | ||
| }; | ||
| window = { | ||
| csd = true; | ||
| opacity = 0.95; | ||
| rounding = 10; | ||
| }; | ||
| } | ||
| ''; | ||
| }; | ||
| }; | ||
|
|
||
| config = lib.mkIf cfg.enable { | ||
|
leiserfg marked this conversation as resolved.
|
||
| assertions = [ | ||
| (lib.hm.assertions.assertPlatform "programs.vicinae" pkgs lib.platforms.linux) | ||
| { | ||
| assertion = cfg.systemd.enable -> cfg.package != null; | ||
| message = "{option}programs.vicinae.systemd.enable requires non null {option}programs.vicinae.package"; | ||
| } | ||
| ]; | ||
| lib.vicinae.mkExtension = ( | ||
| { | ||
| name, | ||
| src, | ||
| }: | ||
| (pkgs.buildNpmPackage { | ||
| inherit name src; | ||
| installPhase = '' | ||
| runHook preInstall | ||
|
|
||
| mkdir -p $out | ||
| cp -r /build/.local/share/vicinae/extensions/${name}/* $out/ | ||
|
|
||
| runHook postInstall | ||
| ''; | ||
| npmDeps = pkgs.importNpmLock { npmRoot = src; }; | ||
| npmConfigHook = pkgs.importNpmLock.npmConfigHook; | ||
| }) | ||
| ); | ||
|
|
||
| lib.vicinae.mkRayCastExtension = ( | ||
| { | ||
| name, | ||
| sha256, | ||
| rev, | ||
| }: | ||
| let | ||
| src = | ||
| pkgs.fetchgit { | ||
| inherit rev sha256; | ||
| url = "https://github.com/raycast/extensions"; | ||
| sparseCheckout = [ | ||
| "/extensions/${name}" | ||
| ]; | ||
| } | ||
| + "/extensions/${name}"; | ||
| in | ||
| (pkgs.buildNpmPackage { | ||
| inherit name src; | ||
| installPhase = '' | ||
| runHook preInstall | ||
|
|
||
| mkdir -p $out | ||
| cp -r /build/.config/raycast/extensions/${name}/* $out/ | ||
|
|
||
| runHook postInstall | ||
| ''; | ||
| npmDeps = pkgs.importNpmLock { npmRoot = src; }; | ||
| npmConfigHook = pkgs.importNpmLock.npmConfigHook; | ||
| }) | ||
| ); | ||
|
|
||
| home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; | ||
|
|
||
| xdg = { | ||
| configFile = { | ||
| "vicinae/vicinae.json" = lib.mkIf (cfg.settings != { }) { | ||
| source = jsonFormat.generate "vicinae-settings" cfg.settings; | ||
| }; | ||
| } | ||
| // lib.mapAttrs' ( | ||
| name: theme: | ||
| lib.nameValuePair "vicinae/themes/${name}.json" { | ||
| source = jsonFormat.generate "vicinae-${name}-theme" theme; | ||
| } | ||
| ) cfg.themes; | ||
|
|
||
| dataFile = builtins.listToAttrs ( | ||
| builtins.map (item: { | ||
| name = "vicinae/extensions/${item.name}"; | ||
| value.source = item; | ||
| }) cfg.extensions | ||
| ); | ||
| }; | ||
|
|
||
| systemd.user.services.vicinae = lib.mkIf (cfg.systemd.enable && cfg.package != null) { | ||
| Unit = { | ||
| Description = "Vicinae server daemon"; | ||
| Documentation = [ "https://docs.vicinae.com" ]; | ||
| After = [ cfg.systemd.target ]; | ||
| PartOf = [ cfg.systemd.target ]; | ||
| BindsTo = [ cfg.systemd.target ]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this unit should have used BindsTo as it blocks logout (at least for plasma) when vicinae service is running.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure that is it? BindsTo is a direct relationship not a reverse one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pretty sure - This fixed logout for me https://github.com/marcusramberg/nix-config/blob/main/home/plasma/default.nix#L375 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also had the same problem with cloudflare warp NixOS/nixpkgs#434733
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I'll make a PR.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }; | ||
| Service = { | ||
| EnvironmentFile = pkgs.writeText "vicinae-env" '' | ||
| USE_LAYER_SHELL=${if cfg.useLayerShell then builtins.toString 1 else builtins.toString 0} | ||
| ''; | ||
| Type = "simple"; | ||
| ExecStart = "${lib.getExe' cfg.package "vicinae"} server"; | ||
| Restart = "always"; | ||
| RestartSec = 5; | ||
| KillMode = "process"; | ||
| }; | ||
| Install = lib.mkIf cfg.systemd.autoStart { | ||
| WantedBy = [ cfg.systemd.target ]; | ||
| }; | ||
| }; | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { lib, pkgs, ... }: | ||
| lib.optionalAttrs (pkgs.stdenv.hostPlatform.isLinux) { | ||
| vicinae-example-settings = ./example-settings.nix; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| { | ||
| pkgs, | ||
| config, | ||
| ... | ||
| }: | ||
|
|
||
| { | ||
| programs.vicinae = { | ||
| enable = true; | ||
| systemd.enable = true; | ||
|
|
||
| settings = { | ||
| faviconService = "twenty"; | ||
| font = { | ||
| size = 10; | ||
| }; | ||
| popToRootOnClose = false; | ||
| rootSearch = { | ||
| searchFiles = false; | ||
| }; | ||
| theme = { | ||
| name = "vicinae-dark"; | ||
| }; | ||
| window = { | ||
| csd = true; | ||
| opacity = 0.95; | ||
| rounding = 10; | ||
| }; | ||
| }; | ||
| themes = { | ||
| base16-default-dark = { | ||
| version = "1.0.0"; | ||
| appearance = "dark"; | ||
| name = "base16 default dark"; | ||
| description = "base16 default dark by Chris Kempson"; | ||
| palette = { | ||
| background = "#181818"; | ||
| foreground = "#d8d8d8"; | ||
| blue = "#7cafc2"; | ||
| green = "#a3be8c"; | ||
| magenta = "#ba8baf"; | ||
| orange = "#dc9656"; | ||
| purple = "#a16946"; | ||
| red = "#ab4642"; | ||
| yellow = "#f7ca88"; | ||
| cyan = "#86c1b9"; | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| extensions = [ | ||
| (config.lib.vicinae.mkRayCastExtension { | ||
| name = "gif-search"; | ||
| sha256 = "sha256-G7il8T1L+P/2mXWJsb68n4BCbVKcrrtK8GnBNxzt73Q="; | ||
| rev = "4d417c2dfd86a5b2bea202d4a7b48d8eb3dbaeb1"; | ||
| }) | ||
| (config.lib.vicinae.mkExtension { | ||
| name = "test-extension"; | ||
| src = | ||
| pkgs.fetchFromGitHub { | ||
| owner = "schromp"; | ||
| repo = "vicinae-extensions"; | ||
| rev = "f8be5c89393a336f773d679d22faf82d59631991"; | ||
| sha256 = "sha256-zk7WIJ19ITzRFnqGSMtX35SgPGq0Z+M+f7hJRbyQugw="; | ||
| } | ||
| + "/test-extension"; | ||
| }) | ||
| ]; | ||
| }; | ||
|
|
||
| nmt.script = '' | ||
| assertFileExists "home-files/.config/vicinae/vicinae.json" | ||
| assertFileExists "home-files/.config/systemd/user/vicinae.service" | ||
| assertFileExists "home-files/.local/share/vicinae/extensions/gif-search/package.json" | ||
| assertFileExists "home-files/.local/share/vicinae/extensions/test-extension/package.json" | ||
| ''; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.