├── .editorconfig ├── .github └── workflows │ ├── docs.yml │ └── test.yml ├── .gitignore ├── .vscode ├── settings.json └── snippets.code-snippets ├── LICENSE ├── Makefile ├── README.md ├── docs ├── .gitignore ├── book.toml ├── default.nix ├── src │ ├── index.md │ └── summary.md ├── templates │ ├── footer.md │ ├── ref-section.md │ └── reference.md └── theme │ ├── catppuccin.css │ ├── custom.css │ └── index.hbs ├── flake.lock ├── flake.nix ├── modules ├── _impl.nix ├── appearance.nix ├── default.nix ├── desktop.nix ├── dock.nix ├── finder.nix ├── safari.nix └── trackpad.nix ├── targets ├── darwin.nix └── home-manager.nix └── tests ├── setup.nix ├── test-appearance-dark.nix ├── test-appearance-light.nix ├── test-appearance.nix ├── test-desktop.nix ├── test-dock.nix ├── test-finder.nix ├── test-reset.nix ├── test-safari.nix ├── test-trackpad-double-tap-drag-lock.nix ├── test-trackpad-three-finger-drag.nix └── test-trackpad.nix /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [Makefile] 11 | indent_style = tab 12 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | name: Build 11 | 12 | permissions: 13 | contents: read 14 | 15 | runs-on: macos-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: cachix/install-nix-action@v30 20 | 21 | - name: Build docs 22 | run: nix -L build github:${{ github.repository }}/${{ github.sha }}#docs 23 | 24 | - name: Prepare docs for upload 25 | run: cp -r -L result/ public/ 26 | 27 | - name: Upload artifact 28 | uses: actions/upload-pages-artifact@v3 29 | with: 30 | path: public/ 31 | 32 | deploy: 33 | name: Deploy 34 | 35 | needs: build 36 | 37 | permissions: 38 | pages: write 39 | id-token: write 40 | 41 | environment: 42 | name: github-pages 43 | url: ${{ steps.deployment.outputs.page_url }} 44 | 45 | runs-on: ubuntu-latest 46 | 47 | steps: 48 | - name: Deploy docs to GitHub Pages 49 | id: deployment 50 | uses: actions/deploy-pages@v4 51 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: "Test" 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | test: 11 | runs-on: macos-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: cachix/install-nix-action@v30 15 | - run: nix flake check 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### VisualStudioCode 2 | .vscode/* 3 | !.vscode/settings.json 4 | !.vscode/tasks.json 5 | !.vscode/launch.json 6 | !.vscode/extensions.json 7 | !.vscode/*.code-snippets 8 | 9 | # Local History for Visual Studio Code 10 | .history/ 11 | 12 | # Built Visual Studio Code Extensions 13 | *.vsix 14 | 15 | ### macOS 16 | # General 17 | .DS_Store 18 | .AppleDouble 19 | .LSOverride 20 | 21 | # Icon must end with two \r 22 | Icon 23 | 24 | # Thumbnails 25 | ._* 26 | 27 | # Files that might appear in the root of a volume 28 | .DocumentRevisions-V100 29 | .fseventsd 30 | .Spotlight-V100 31 | .TemporaryItems 32 | .Trashes 33 | .VolumeIcon.icns 34 | .com.apple.timemachine.donotpresent 35 | 36 | # Directories potentially created on remote AFP share 37 | .AppleDB 38 | .AppleDesktop 39 | Network Trash Folder 40 | Temporary Items 41 | .apdisk 42 | 43 | ### Vim 44 | # Swap 45 | [._]*.s[a-v][a-z] 46 | !*.svg # comment out if you don't need vector files 47 | [._]*.sw[a-p] 48 | [._]s[a-rt-v][a-z] 49 | [._]ss[a-gi-z] 50 | [._]sw[a-p] 51 | 52 | # Session 53 | Session.vim 54 | Sessionx.vim 55 | 56 | # Temporary 57 | .netrwhist 58 | *~ 59 | # Auto-generated tag files 60 | tags 61 | # Persistent undo 62 | [._]*.un~ 63 | 64 | ### direnv 65 | .direnv 66 | .envrc 67 | 68 | ### Custom 69 | result 70 | TODO.md 71 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": ["catppuccin", "nixos", "nixpkgs", "pkgs", "trackpad"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/snippets.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Nix Module": { 3 | "prefix": "module", 4 | "body": [ 5 | "{ config, pkgs, lib, ... }:", 6 | "", 7 | "let", 8 | " cfg = config.plist.${1:name};", 9 | "", 10 | " inherit (pkgs.callPackage ../lib { }) mkNullableOption writePlist;", 11 | "in", 12 | "", 13 | "{", 14 | " options.plist.${1:name} = with lib; {", 15 | " ${2:enable} = mkNullableOption {", 16 | " type = types.bool;", 17 | " description = ''", 18 | " Whether to $3", 19 | " '';", 20 | " };", 21 | " };", 22 | "", 23 | " config.plist.out = writePlist {};", 24 | "}", 25 | "" 26 | ], 27 | "description": "Nix Module" 28 | }, 29 | "Nix Module Test": { 30 | "prefix": "test", 31 | "body": [ 32 | "{", 33 | " imports = [", 34 | " ../modules/$1.nix", 35 | " ];", 36 | "", 37 | " plist.$1 = {", 38 | " $2", 39 | " };", 40 | "", 41 | " test = ''", 42 | " has todo$0", 43 | " '';", 44 | "}", 45 | "" 46 | ], 47 | "description": "Nix Module Test" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 z0al 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | @nix flake check --show-trace --option log-lines 1000 3 | 4 | site: 5 | @nix build .#docs && serve ./result 6 | 7 | watch: 8 | @plistwatch 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # plist-manager 2 | 3 | 4 | 5 | 6 | 7 | ## Introduction 8 | 9 | Plist-manager (PM) is a Nix module for managing macOS user defaults. Unlike the built-in options offered by [nix-darwin](https://github.com/LnL7/nix-darwin) and [home-manager](https://github.com/nix-community/home-manager), PM provides the following advantages: 10 | 11 | - Human-friendly naming of domains and options, e.g., `trackpad.draggingStyle = "three-fingers"`. 12 | - Automatic reloading of system settings with `activateSettings -u` after applying changes. 13 | - Unsetting an option or explicitly setting it to `null` _resets_ its value, effectively performing a `defaults delete