···120120121121If one of your favourite plugins isn't packaged, you can package it yourself:
122122123123-```
123123+```nix
124124{ config, pkgs, ... }:
125125126126let
···153153 ];
154154}
155155```
156156+157157+### Specificities for some plugins
158158+#### Tree sitter
159159+160160+By default `nvim-treesitter` encourages you to download, compile and install
161161+the required tree-sitter grammars at run time with `:TSInstall`. This works
162162+poorly on NixOS. Instead, to install the `nvim-treesitter` plugins with a set
163163+of precompiled grammars, you can use `nvim-treesitter.withPlugins` function:
164164+165165+```nix
166166+(pkgs.neovim.override {
167167+ configure = {
168168+ packages.myPlugins = with pkgs.vimPlugins; {
169169+ start = [
170170+ (nvim-treesitter.withPlugins (
171171+ plugins: with plugins; [
172172+ tree-sitter-nix
173173+ tree-sitter-python
174174+ ]
175175+ ))
176176+ ];
177177+ };
178178+ };
179179+})
180180+```
181181+182182+To enable all grammars packaged in nixpkgs, use `(pkgs.vimPlugins.nvim-treesitter.withPlugins (plugins: pkgs.tree-sitter.allGrammars))`.
156183157184## Managing plugins with vim-plug {#managing-plugins-with-vim-plug}
158185
+63-11
nixos/modules/services/misc/klipper.nix
···22with lib;
33let
44 cfg = config.services.klipper;
55- package = pkgs.klipper;
65 format = pkgs.formats.ini { mkKeyValue = generators.mkKeyValueDefault {} ":"; };
76in
87{
···1110 services.klipper = {
1211 enable = mkEnableOption "Klipper, the 3D printer firmware";
13121313+ package = mkOption {
1414+ type = types.package;
1515+ default = pkgs.klipper;
1616+ description = "The Klipper package.";
1717+ };
1818+1919+ inputTTY = mkOption {
2020+ type = types.path;
2121+ default = "/run/klipper/tty";
2222+ description = "Path of the virtual printer symlink to create.";
2323+ };
2424+2525+ apiSocket = mkOption {
2626+ type = types.nullOr types.path;
2727+ default = null;
2828+ example = "/run/klipper/api";
2929+ description = "Path of the API socket to create.";
3030+ };
3131+1432 octoprintIntegration = mkOption {
1533 type = types.bool;
1634 default = false;
1735 description = "Allows Octoprint to control Klipper.";
1836 };
19373838+ user = mkOption {
3939+ type = types.nullOr types.str;
4040+ default = null;
4141+ description = ''
4242+ User account under which Klipper runs.
4343+4444+ If null is specified (default), a temporary user will be created by systemd.
4545+ '';
4646+ };
4747+4848+ group = mkOption {
4949+ type = types.nullOr types.str;
5050+ default = null;
5151+ description = ''
5252+ Group account under which Klipper runs.
5353+5454+ If null is specified (default), a temporary user will be created by systemd.
5555+ '';
5656+ };
5757+2058 settings = mkOption {
2159 type = format.type;
2260 default = { };
···30683169 ##### implementation
3270 config = mkIf cfg.enable {
3333- assertions = [{
3434- assertion = cfg.octoprintIntegration -> config.services.octoprint.enable;
3535- message = "Option klipper.octoprintIntegration requires Octoprint to be enabled on this system. Please enable services.octoprint to use it.";
3636- }];
7171+ assertions = [
7272+ {
7373+ assertion = cfg.octoprintIntegration -> config.services.octoprint.enable;
7474+ message = "Option klipper.octoprintIntegration requires Octoprint to be enabled on this system. Please enable services.octoprint to use it.";
7575+ }
7676+ {
7777+ assertion = cfg.user != null -> cfg.group != null;
7878+ message = "Option klipper.group is not set when a user is specified.";
7979+ }
8080+ ];
37813882 environment.etc."klipper.cfg".source = format.generate "klipper.cfg" cfg.settings;
39834040- systemd.services.klipper = {
8484+ services.klipper = mkIf cfg.octoprintIntegration {
8585+ user = config.services.octoprint.user;
8686+ group = config.services.octoprint.group;
8787+ };
8888+8989+ systemd.services.klipper = let
9090+ klippyArgs = "--input-tty=${cfg.inputTTY}"
9191+ + optionalString (cfg.apiSocket != null) " --api-server=${cfg.apiSocket}";
9292+ in {
4193 description = "Klipper 3D Printer Firmware";
4294 wantedBy = [ "multi-user.target" ];
4395 after = [ "network.target" ];
44964597 serviceConfig = {
4646- ExecStart = "${package}/lib/klipper/klippy.py --input-tty=/run/klipper/tty /etc/klipper.cfg";
9898+ ExecStart = "${cfg.package}/lib/klipper/klippy.py ${klippyArgs} /etc/klipper.cfg";
4799 RuntimeDirectory = "klipper";
48100 SupplementaryGroups = [ "dialout" ];
4949- WorkingDirectory = "${package}/lib";
5050- } // (if cfg.octoprintIntegration then {
5151- Group = config.services.octoprint.group;
5252- User = config.services.octoprint.user;
101101+ WorkingDirectory = "${cfg.package}/lib";
102102+ } // (if cfg.user != null then {
103103+ Group = cfg.group;
104104+ User = cfg.user;
53105 } else {
54106 DynamicUser = true;
55107 User = "klipper";
+9-1
nixos/modules/services/ttys/getty.nix
···66 cfg = config.services.getty;
7788 baseArgs = [
99- "--login-program" "${pkgs.shadow}/bin/login"
99+ "--login-program" "${cfg.loginProgram}"
1010 ] ++ optionals (cfg.autologinUser != null) [
1111 "--autologin" cfg.autologinUser
1212 ] ++ optionals (cfg.loginOptions != null) [
···3636 description = ''
3737 Username of the account that will be automatically logged in at the console.
3838 If unspecified, a login prompt is shown as usual.
3939+ '';
4040+ };
4141+4242+ loginProgram = mkOption {
4343+ type = types.path;
4444+ default = "${pkgs.shadow}/bin/login";
4545+ description = ''
4646+ Path to the login binary executed by agetty.
3947 '';
4048 };
4149