first commit

This commit is contained in:
Louis Dalibard 2024-12-24 16:04:27 +01:00
commit 870c6176c6
157 changed files with 9882 additions and 0 deletions

13
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,13 @@
---
version: 2
updates:
- package-ecosystem: github-actions
commit-message:
prefix: ci
directory: /
schedule:
interval: daily

45
.github/workflows/backport.yml vendored Normal file
View File

@ -0,0 +1,45 @@
# Derived from https://github.com/NixOS/nixpkgs/blob/2ab6f6d61630889491f86396b27a76ffb6fbc7bb/.github/workflows/backport.yml
name: Backport
on:
pull_request_target:
types: [closed, labeled]
permissions: {}
jobs:
backport:
name: Backport
runs-on: ubuntu-latest
if: >
(
github.repository_owner == 'danth' &&
github.event.pull_request.merged == true &&
(github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
)
steps:
# Use a GitHub App rather than the default token so that GitHub Actions
# workflows may run on the created pull request.
- name: Create GitHub access token
uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.BACKPORT_APP_ID }}
private-key: ${{ secrets.BACKPORT_PRIVATE_KEY }}
- name: Checkout original pull request
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
token: ${{ steps.app-token.outputs.token }}
- name: Create backport pull request
uses: korthout/backport-action@v3
with:
github_token: ${{ steps.app-token.outputs.token }}
pull_title: "[${target_branch}] ${pull_title}"
pull_description: |-
This is an automated backport of #${pull_number}.

61
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,61 @@
name: Build
on:
push:
branches:
- master
- release-**
pull_request:
permissions:
contents: read
jobs:
evaluate:
name: List packages
runs-on: ubuntu-latest
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
extra-conf: |
extra-experimental-features = nix-command flakes
- name: Set up cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: List packages
id: list-packages
run: |
nix flake show github:${{ github.repository }}/${{ github.event.pull_request.head.sha || github.sha }} --json | jq -rc 'to_entries | map(.key as $type | select($type == "checks" or $type == "packages") | .value | to_entries | map(.key as $arch | select($arch == "x86_64-linux" or $arch == "x86_64-darwin") | .value | to_entries | map({type: $type, arch: $arch, os: (if $arch == "x86_64-linux" then "ubuntu-latest" else "macos-latest" end), key: .key})) | flatten) | flatten | "packages=\(.)"' >> $GITHUB_OUTPUT
outputs:
packages: ${{ steps.list-packages.outputs.packages }}
build:
needs: evaluate
strategy:
fail-fast: false
matrix:
build: ${{ fromJSON(needs.evaluate.outputs.packages) }}
name: ${{ matrix.build.key }} on ${{ matrix.build.arch }}
runs-on: ${{ matrix.build.os }}
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
extra-conf: |
extra-experimental-features = nix-command flakes
- name: Set up cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Build ${{ matrix.build.key }}
run: nix -L build github:${{ github.repository }}/${{ github.event.pull_request.head.sha || github.sha }}#${{ matrix.build.type }}.${{ matrix.build.arch }}.${{ matrix.build.key }} --no-update-lock-file

57
.github/workflows/docs.yml vendored Normal file
View File

@ -0,0 +1,57 @@
name: Docs
on:
push:
branches:
- master
jobs:
build:
name: Build
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
extra-conf: |
extra-experimental-features = nix-command flakes
- name: Set up cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Build docs
run: nix -L build github:${{ github.repository }}/${{ github.sha }}#docs
- name: Prepare docs for upload
run: cp -r --dereference --no-preserve=mode,ownership result/ public/
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: public/
deploy:
name: Deploy
needs: build
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Deploy docs to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

42
.github/workflows/lint.yml vendored Normal file
View File

@ -0,0 +1,42 @@
name: Lint
on: pull_request
permissions:
contents: read
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
extra-conf: |
extra-experimental-features = nix-command flakes
- name: Set up cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Install tools
run: |
flake='github:nixos/nixpkgs/e913ae340076bbb73d9f4d3d065c2bca7caafb16'
nix profile install "${flake}#statix"
nix profile install "${flake}#deadnix"
nix profile install "${flake}#jq"
- name: Checkout repository
uses: actions/checkout@v4
- name: Run statix
run: |
statix check --format json |\
jq --raw-output '.file as $file | .report[] | .severity as $severity | .diagnostics[] | "::warning file=\($file),line=\(.at.from.line),col=\(.at.from.column)::\(.message)"'
- name: Run deadnix
run: |
deadnix --no-lambda-arg --output-format json |\
jq --raw-output '.file as $file | .results[] | "::warning file=\($file),line=\(.line),col=\(.column)::\(.message)"'

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
result
result-*

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-2024 Daniel Thwaites and the Stylix contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

68
README.md Normal file
View File

@ -0,0 +1,68 @@
# Stylix
Stylix is a NixOS module which applies the same colour scheme, font and
wallpaper to a range of applications and desktop environments.
## What's this?
[base16.nix](https://github.com/SenchoPens/base16.nix#readme) allows you to
import colours from [base16](https://github.com/chriskempson/base16#readme)
into Nix code. Stylix takes this a step further:
- Automatically colours and changes the font of apps
- Sets your wallpaper
- Exports the colour scheme to be used manually for anything we missed
- Can also generate themes based on an image
For those not familiar with [NixOS](https://nixos.org/) and
[Home Manager](https://github.com/nix-community/home-manager#readme):
- NixOS is a Linux distribution
- Home Manager is a program which runs anywhere
- Both use the Nix language and package manager
- Both let you install programs and change settings via code
Stylix supports either NixOS + Home Manager, or Home Manager on its own.
Certain features are only available with NixOS.
## Resources
Please refer to the [Stylix book](https://danth.github.io/stylix/)
for instructions and a list of supported apps.
For a visual guide, watch the [*Ricing Linux Has Never Been Easier | NixOS +
Stylix*](https://youtu.be/ljHkWgBaQWU) YouTube video by
[Vimjoyer](https://www.youtube.com/@vimjoyer).
> [!NOTE]
>
> It's now necessary to include `stylix.enable = true` in your configuration
> for any other settings to take effect. This is not mentioned in the video
> linked above.
If you have any questions, you are welcome to
join our [Matrix room](https://matrix.to/#/#stylix:danth.me),
or ask on [GitHub Discussions](https://github.com/danth/stylix/discussions).
## Example configurations
### GNOME 46
![GNOME 46](./gnome.png)
Photos by [Clay Banks](https://unsplash.com/photos/three-bicycles-parked-in-front-of-building-hwLAI5lRhdM)
and [Derrick Cooper](https://unsplash.com/photos/brown-road-in-forest-during-daytime-L505cPnmIds).
Try a live demo of this theme by running
`nix run github:danth/stylix#testbed-gnome-light` or
`nix run github:danth/stylix#testbed-gnome-dark`.
### KDE Plasma 5
![KDE Plasma 5](./kde.png)
Photos by [Aniket Deole](https://unsplash.com/photos/mountain-surrounded-by-trees-under-cloudy-sky-T-tOgjWZ0fQ)
and [Tom Gainor](https://unsplash.com/photos/landscape-photography-of-body-of-water-overlooking-mountain-range-ZqLeQDjY6fY).
KDE theming is still a work in progress - so some manual steps may be needed
to apply the settings completely.

6
default.nix Normal file
View File

@ -0,0 +1,6 @@
(import (let lock = builtins.fromJSON (builtins.readFile ./flake.lock);
in fetchTarball {
url =
"https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}) { src = ./.; }).defaultNix

9
docs/book.toml Normal file
View File

@ -0,0 +1,9 @@
[book]
title = "Stylix"
language = "en"
[output.html]
site-url = "/stylix/"
git-repository-url = "https://github.com/danth/stylix"
edit-url-template = "https://github.com/danth/stylix/edit/master/docs/{path}"

66
docs/default.nix Normal file
View File

@ -0,0 +1,66 @@
{ pkgs, lib, inputs, ... }:
let
makeOptionsDoc = configuration: pkgs.nixosOptionsDoc {
inherit (configuration) options;
# Filter out any options not beginning with `stylix`
transformOptions = option: option // {
visible = option.visible &&
builtins.elemAt option.loc 0 == "stylix";
};
};
nixos = makeOptionsDoc
(lib.nixosSystem {
inherit (pkgs) system;
modules = [
inputs.home-manager.nixosModules.home-manager
inputs.self.nixosModules.stylix
./settings.nix
];
});
homeManager = makeOptionsDoc
(inputs.home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
inputs.self.homeManagerModules.stylix
./settings.nix
{
home = {
homeDirectory = "/home/book";
stateVersion = "22.11";
username = "book";
};
}
];
});
in pkgs.stdenvNoCC.mkDerivation {
name = "stylix-book";
src = ./.;
patchPhase = ''
cp ${../README.md} src/README.md
cp ${../gnome.png} src/gnome.png
cp ${../kde.png} src/kde.png
# mdBook doesn't support this Markdown extension yet
substituteInPlace **/*.md \
--replace-quiet '> [!NOTE]' '> **Note**' \
--replace-quiet '> [!TIP]' '> **Tip**' \
--replace-quiet '> [!IMPORTANT]' '> **Important**' \
--replace-quiet '> [!WARNING]' '> **Warning**' \
--replace-quiet '> [!CAUTION]' '> **Caution**'
# The "declared by" links point to a file which only exists when the docs
# are built locally. This removes the links.
sed '/*Declared by:*/,/^$/d' <${nixos.optionsCommonMark} >>src/options/nixos.md
sed '/*Declared by:*/,/^$/d' <${homeManager.optionsCommonMark} >>src/options/hm.md
'';
buildPhase = ''
${pkgs.mdbook}/bin/mdbook build --dest-dir $out
'';
}

26
docs/settings.nix Normal file
View File

@ -0,0 +1,26 @@
# Dummy values to avoid errors when generating the documentation.
{
stylix = {
image = "/a/b/c";
base16Scheme = {
base00 = "ffffff";
base01 = "ffffff";
base02 = "ffffff";
base03 = "ffffff";
base04 = "ffffff";
base05 = "ffffff";
base06 = "ffffff";
base07 = "ffffff";
base08 = "ffffff";
base09 = "ffffff";
base0A = "ffffff";
base0B = "ffffff";
base0C = "ffffff";
base0D = "ffffff";
base0E = "ffffff";
base0F = "ffffff";
};
};
}

19
docs/src/SUMMARY.md Normal file
View File

@ -0,0 +1,19 @@
[Introduction](README.md)
# User guide
- [Installation](installation.md)
- [Configuration](configuration.md)
- [Tips and tricks](tricks.md)
# Reference
- [NixOS options](options/nixos.md)
- [Home Manager options](options/hm.md)
# Contributing
- [Commit Convention](commit_convention.md)
- [Adding modules](modules.md)
- [Testbeds](testbeds.md)
- [Style guide](styling.md)

View File

@ -0,0 +1,30 @@
# Commit Convention
To keep things consistent, commit messages should follow a format
[similar to Nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md#commit-conventions):
```
«scope»: «summary»
«motivation for change»
```
Where the scope is one of:
| Scope | Purpose |
|----------------|------------------------------------------------------------------------|
| `ci` | Changes to GitHub Actions workflows. |
| `doc` | Changes to the website, `README.md`, and so on. |
| `stylix` | Changes in the `stylix` directory, `flake.nix`, and other global code. |
| Name of target | Changes to code for a particular target. |
| `treewide` | Changes across many targets. |
The scope is meant to indicate which area of the code was changed. Specifying
the type of change, such as `feat` or `fix`, is not necessary. Dependency
updates should use whichever scope they are related to.
The summary should start with a lowercase letter, and should not end with
punctuation.
Most commits to `master` will also include a pull request number in brackets
after the summary. GitHub adds this automatically when creating a squash merge.

218
docs/src/configuration.md Normal file
View File

@ -0,0 +1,218 @@
# Configuration
## Enable
To enable the Stylix module, declare:
```nix
{
stylix.enable = true;
}
```
> [!NOTE]
>
> The global enable option was recently added, so you may come across old
> examples which don't include it. No other settings will take effect unless
> `stylix.enable` is set to `true`.
## Wallpaper
To start theming, you need to set a wallpaper image.
```nix
{
stylix.image = ./wallpaper.png;
}
```
The option accepts derivations as well as paths, so you can fetch an image
directly from the internet:
```nix
{
stylix.image = pkgs.fetchurl {
url = "https://www.pixelstalk.net/wp-content/uploads/2016/05/Epic-Anime-Awesome-Wallpapers.jpg";
sha256 = "enQo3wqhgf0FEPHj2coOCvo7DuZv+x5rL/WIo4qPI50=";
};
}
```
## Color scheme
### Generated schemes
If you only set a wallpaper, Stylix will use a
[genetic algorithm](https://en.wikipedia.org/wiki/Genetic_algorithm)
to create a color scheme. The quality of these schemes can vary, but more
colorful images tend to have better results.
You can force a light or dark scheme using the polarity option:
```nix
{
stylix.polarity = "dark";
}
```
The current scheme can be previewed in a web browser at either
[`/etc/stylix/palette.html`](file:///etc/stylix/palette.html) for NixOS, or
`~/.config/stylix/palette.html` for Home Manager.
### Handmade schemes
If you prefer a handmade color scheme, you can choose anything from
[the Tinted Theming repository](https://github.com/tinted-theming/schemes):
```nix
{
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-dark-hard.yaml";
}
```
This option also accepts other files and formats supported by
[`mkSchemeAttrs`](https://github.com/SenchoPens/base16.nix/blob/main/DOCUMENTATION.md#mkschemeattrs).
### Overriding
For convenience, it is possible to override parts of `stylix.base16Scheme` using
`stylix.override`. Anything that
[base16.nix](https://github.com/SenchoPens/base16.nix) accepts as override is
valid.
When using both the Home Manager and NixOS modules, both the system overrides
and the user-provided one are used in the user configuration if
`stylix.base16Scheme` is not changed in the user config. If that is the case,
only the user override is used.
### Extending
When passing colors to unsupported targets or creating custom modules, it
is possible to access values from the configured color scheme through
`config.lib.stylix.colors`.
An overview of the available values is shown below.
```nix
config.lib.stylix.colors = {
base08 = "ff0000";
base08-hex-r = "ff";
base08-dec-r = "0.996094";
# ...
red = "ff0000";
# ...
withHashtag = {
base08 = "#ff0000";
# ...
};
};
```
This attrset is generated by `mkSchemeAttrs` from `base16.nix`. Refer to the
[documentation](https://github.com/SenchoPens/base16.nix/blob/main/DOCUMENTATION.md#mkschemeattrs)
for more info.
For more complex configurations you may find it simpler to use
[mustache](http://mustache.github.io/) templates to generate output files.
See [base16.nix](https://github.com/SenchoPens/base16.nix) documentation for
usage examples.
## Fonts
The default combination of fonts is:
```nix
{
stylix.fonts = {
serif = {
package = pkgs.dejavu_fonts;
name = "DejaVu Serif";
};
sansSerif = {
package = pkgs.dejavu_fonts;
name = "DejaVu Sans";
};
monospace = {
package = pkgs.dejavu_fonts;
name = "DejaVu Sans Mono";
};
emoji = {
package = pkgs.noto-fonts-emoji;
name = "Noto Color Emoji";
};
};
}
```
These can be changed as you like.
To make things look more uniform, you could replace the serif font with
the sans-serif font:
```nix
{
stylix.fonts.serif = config.stylix.fonts.sansSerif;
}
```
Or even choose monospace for everything:
```nix
{
stylix.fonts = {
serif = config.stylix.fonts.monospace;
sansSerif = config.stylix.fonts.monospace;
emoji = config.stylix.fonts.monospace;
};
}
```
## Home Manager inheritance
By default, if Home Manager is used as part of NixOS, then Stylix will be
automatically installed for all users, and the NixOS theme will become their
default settings.
This is convenient for single-user systems, since you can configure everything
once at the system level and it will automatically carry over. For multi-user
systems, you can override the settings within Home Manager to select a different
theme for each user.
You may prefer to disable inheritance entirely, and set up the Home Manager
version of Stylix yourself if required. Refer to the options
[`stylix.homeManagerIntegration.autoImport`](options/nixos.md#stylixhomemanagerintegrationautoimport)
and
[`stylix.homeManagerIntegration.followSystem`](options/nixos.md#stylixhomemanagerintegrationfollowsystem)
to customize this.
> [!NOTE]
>
> There is a special case involving the
> [`stylix.base16Scheme`](options/nixos.md#stylixbase16scheme)
> option:
>
> If the wallpaper in a Home Manager configuration is changed, then Home Manager
> will stop inheriting the color scheme from NixOS. This allows Home Manager
> configurations to use the automatic palette generator without being overridden.
>
> Similarly, [`stylix.override`](options/nixos.md#stylixoverride) is not inherited
> if the color scheme is different.
## Turning targets on and off
In Stylix terms, a target is anything which can have colors, fonts or a
wallpaper applied to it. Each module in this repository should correspond to a
target of the same name.
Each target has an option like `stylix.targets.«target».enable` to turn its
styling on or off. Normally, it's turned on automatically when the target is
installed. You can set `stylix.autoEnable = false` to opt out of this
behaviour, in which case you'll need to manually enable each target you want to
be styled.
Targets are different between Home Manager and NixOS, and sometimes available
in both cases. If both are available, it is always correct to enable both.
The reference pages have a list of targets for [NixOS](options/nixos.md) and
[Home Manager](options/hm.md) respectively.

132
docs/src/installation.md Normal file
View File

@ -0,0 +1,132 @@
# Installation
## NixOS
You can install Stylix into your NixOS configuration using [Flakes][nix-flakes].
This will provide theming for system level programs such as bootloaders, splash
screens, and display managers.
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
stylix.url = "github:danth/stylix";
};
outputs = { nixpkgs, stylix, ... }: {
nixosConfigurations."«hostname»" = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ stylix.nixosModules.stylix ./configuration.nix ];
};
};
}
```
<small>Minimal `flake.nix` for a NixOS configuration.</small>
Many applications cannot be configured system wide, so Stylix will also need
[Home Manager][nix-hm] to be able to change their settings within your home
directory.
[Installing Home Manager as a NixOS module](https://nix-community.github.io/home-manager/index.xhtml#sec-install-nixos-module)
is highly recommended if you don't use it already. This will combine it with
your existing configuration, so you don't need to run any extra commands when
you rebuild, and the theme you set in NixOS will automatically be used for Home
Manager too.
When Stylix is installed to a NixOS configuration, it will automatically set up
its Home Manager modules if it detects that Home Manager is available. You can
theoretically use it without installing Home Manager, however most features
will be unavailable.
## nix-darwin
You can install Stylix into your nix-darwin configuration in a similar fashion
to NixOS via [Flakes][nix-flakes].
```nix
{
inputs = {
darwin = {
url = "github:LnL7/nix-darwin";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
stylix.url = "github:danth/stylix";
};
outputs = { darwin, nixpkgs, stylix, ... }: {
darwinConfigurations."«hostname»" = darwin.lib.darwinSystem {
system = "aarch64-darwin";
modules = [ stylix.darwinModules.stylix ./configuration.nix ];
};
};
}
```
<small>Minimal `flake.nix` for a nix-darwin configuration.</small>
While this won't have an effect on the looks of MacOS, since we don't have the
controls to theme it like we do NixOS, it will automatically set up the [Home
Manager][nix-hm] modules for you.
## Home Manager
If you would prefer to use the standalone version of Home Manager, you can
install Stylix directly into your Home Manager configuration instead. This
could be useful if you are on another operating system, or a machine which
is managed by someone else.
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
stylix.url = "github:danth/stylix";
};
outputs = { nixpkgs, home-manager, stylix, ... }: {
homeConfigurations."«username»" = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
modules = [ stylix.homeManagerModules.stylix ./home.nix ];
};
};
}
```
<small>Minimal `flake.nix` for a Home Manager configuration.</small>
If you choose to use both NixOS and Home Manager but configure them separately,
you will need to copy the settings described below into both of your
configurations, as keeping them separate means that they cannot follow each
other automatically.
## Without flakes
If you haven't enabled flakes yet or don't want to use this feature, `default.nix`
re-exports all the flake outputs, without requiring flakes to be enabled. This means
that once you have a copy of this repo, using either a local checkout,
[niv](https://github.com/nmattia/niv), or any other method, you can import it to
get the NixOS module as the `nixosModules.stylix` attribute and the Home Manager
module as the `homeManagerModules.stylix` attribute.
```nix
let
stylix = pkgs.fetchFromGitHub {
owner = "danth";
repo = "stylix";
rev = "...";
sha256 = "...";
};
in {
imports = [ (import stylix).homeManagerModules.stylix ];
stylix = {
enable = true;
image = ./wallpaper.jpg;
};
}
```
<small>Example usage of the Home Manager module without flakes.</small>
[nix-flakes]: https://wiki.nixos.org/wiki/Flakes
[nix-hm]: https://github.com/nix-community/home-manager

119
docs/src/modules.md Normal file
View File

@ -0,0 +1,119 @@
# Adding modules
## Development setup
Currently the easiest way to test Stylix is to use the new code in your
actual configuration.
You might find it useful to change the flake reference in your configuration
from `github:danth/stylix` to `git+file:/home/user/path/to/stylix`
so that you don't need to push your changes to GitHub during testing.
Then, remember to run `nix flake lock --update-input stylix` to refresh the
flake each time you make an edit.
Nix only reads files which are tracked by Git, so you also need to
`git add «file»` after creating a new file.
## Module naming
Modules should be named like `modules/«name»/«platform».nix`. For example,
`modules/avizo/hm.nix` is a Home Manager module which themes Avizo.
The following platforms are supported:
- NixOS (`nixos`)
- Home Manager (`hm`)
- Nix-Darwin (`darwin`)
Correctly named modules will be imported automatically.
Other files needed by the module can also be stored within the
`modules/«name»` folder, using any name which is not on the list above.
## Module template
All modules should have an enable option created using `mkEnableTarget`.
This is similar to
[`mkEnableOption`](https://nix-community.github.io/docnix/reference/lib/options/lib-options-mkenableoption/)
from the standard library, however it integrates with
[`stylix.enable`](./options/nixos.md#stylixenable) and
[`stylix.autoEnable`](./options/nixos.md#stylixautoenable)
and generates more specific documentation.
A general format for modules is shown below.
```nix
{ config, lib, ... }:
{
options.stylix.targets.«name».enable =
config.lib.stylix.mkEnableTarget "«human readable name»" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.«name».enable) {
programs.«name».backgroundColor = config.lib.stylix.colors.base00;
};
}
```
The human readable name will be inserted into the following sentence:
> Whether to enable theming for «human readable name».
If your module will touch options outside of `programs.«name»` or `services.«name»`,
it should include an additional condition in `mkIf` to prevent any effects
when the target is not installed.
The boolean value after `mkEnableTarget` should be changed to `false` if
one of the following applies:
- The module requires further manual setup to work correctly.
- There is no reliable way to detect whether the target is installed, *and*
enabling it unconditionally would cause problems.
## Testbeds
Adding [testbeds](./testbeds.md) for new modules is encouraged, but not
mandatory.
## How to apply colors
Refer to the [style guide](./styling.md) to see how colors are named,
and where to use each one.
The colors are exported under `config.lib.stylix.colors`, which originates from
[`mkSchemeAttrs`](https://github.com/SenchoPens/base16.nix/blob/main/DOCUMENTATION.md#mkschemeattrs).
You can use the values directly:
```nix
{
environment.variables.MY_APPLICATION_COLOR = config.lib.stylix.colors.base05;
}
```
Or you can create a [Mustache](http://mustache.github.io/) template and use
it as a function. This returns a derivation which builds the template.
```nix
{
environment.variables.MY_APPLICATION_CONFIG_FILE =
let configFile = config.lib.stylix.colors {
template = ./config.toml.mustache;
extension = ".toml";
};
in "${configFile}";
}
```
Setting options through an existing NixOS or Home Manager module is preferable
to generating whole files, since users will have the option of overriding things
individually.
Also note that reading generated files with `builtins.readFile` can be very
slow and should be avoided.
## How to apply other things
For everything else, like fonts and wallpapers, you can just take option values
directly from `config`. See the reference pages for a list of options.

24
docs/src/options/hm.md Normal file
View File

@ -0,0 +1,24 @@
# Home Manager options
The following options can only be set in a Home Manager configuration.
If you combined Home Manager with your NixOS configuration, write these
options within a Home Manager section, either for all users:
```nix
home-manager.sharedModules = [{
stylix.targets.xyz.enable = false;
}];
```
Or for a specific user:
```nix
home-manager.users.«name» = {
stylix.targets.xyz.enable = false;
};
```
[Read more about per-user themes.](../configuration.md#multi-user-configurations)
<!-- Auto-generated documentation will be added below. -->

View File

@ -0,0 +1,5 @@
# NixOS options
The following options can only be set in a NixOS configuration.
<!-- Auto-generated documentation will be added below. -->

147
docs/src/styling.md Normal file
View File

@ -0,0 +1,147 @@
# Style guide
The [base16 style guide](https://github.com/chriskempson/base16/blob/main/styling.md)
is generally targeted towards text editors. Stylix aims to support a variety of
other applications, and as such it requires its own guide to keep colours
consistent. Towards this goal we will define several common types of
applications and how to style each of them using the available colours.
Please keep in mind that this is a general guide; there will be several
applications that don't fit into any of the groups below. In this case it is up
to the committer to make sure said application fits in stylistically with the
rest of the themed applications.
It is also importent to note that this is a growing theming guide and when theming an application and you find the guide to be lacking in any way in
terms of direction, you are encouraged to open an issue regarding what you would like to see added to the style guide.
## Terms
### Alternate
An alternate color should be used when something needs to look separate while not
being drastically different. The smaller or less common element should use the
alternate color.
![Appearance tab in GNOME settings](https://github.com/SomeGuyNamedMy/stylix/assets/28959268/e29f9fec-7b68-45ce-95ef-90d8e787c991)
For example, each section in this settings menu uses the alternate background color
to separate it from the rest of the window, which is using the default background.
### On/Off
This is for toggles or simple status indicators which have an obvious on and off state.
![Toggles in GNOME quick settings](https://github.com/SomeGuyNamedMy/stylix/assets/28959268/710056f6-26f7-47d4-bd2f-1384185fb46a)
In the screenshot above the Wired and Night Light buttons are on, Power Mode is off.
### Lists and selections
A list of items to select between, such as tabs in a web browser. The selection is
the currently active item, or there could be multiple selected depending on the use case.
![Sidebar of Nautilus file manager](https://github.com/SomeGuyNamedMy/stylix/assets/28959268/3b893677-75e1-4190-b3ab-b07d10930b19)
## General colors
- Default background: base00
- Alternate background: base01
- Selection background: base02
- Default text: base05
- Alternate text: base04
- Warning: base0A
- Urgent: base09
- Error: base08
## Window Managers
Window Managers arrange windows and provide decorations like title bars and
borders. Examples include Sway and i3.
This does not include applications bundled with the desktop environment such as
file managers, which would fall into the general category. Desktop helpers such as
taskbars and menus are not technically part of the window manager, although they're
often configured in the same place.
An urgent window is one which is grabbing for attention - Windows shows this by
a flashing orange taskbar icon.
- Unfocused window border: base03
- Focused window border: base0D
- Unfocused window border in group: base03
- Focused window border in group: base0D
- Urgent window border: base08
- Window title text: base05
## Notifications and Popups
Notifications and popups are any application overlay intended to be displayed
over other applications. Examples include the mako notification daemon and
avizo.
- Window border: base0D
- Low urgency background color: base06
- Low urgency text color: base0A
- High urgency background color: base0F
- High urgency text color: base08
- Incomplete part of progress bar: base01
- Complete part of progress bar: base02
## Desktop Helpers
Applications that fall under this group are applications that complement the
window management facilities of whatever window manager the user is using.
Examples of this include waybar and polybar, as well as the similar programs
that are part of KDE and GNOME.
### Light text color widgets
Refer to general colors above.
### Dark text color widgets
These widgets use a different text color than usual to ensure it's still
readable when the background is more vibrant.
- Default text color: base00
- Alternate text color: base01
- Item on background color: base0E
- Item off background color: base0D
- Alternate item on background color: base09
- Alternate item off background color: base02
- List unselected background: base0D
- List selected background: base03
## Images
For creating modified versions of logos, icons, etc; where we would rather the
colors be similar to the original.
Note that the colors provided by the scheme won't necessarily match the names given
below, although most handmade schemes do.
- Background color: base00
- Alternate background color: base01
- Main color: base05
- Alternate main color: base04
- Red: base08
- Orange: base09
- Yellow: base0A
- Green: base0B
- Cyan: base0C
- Blue: base0D
- Purple: base0E
- Brown: base0F
![Recolored systemd logo](https://github.com/SomeGuyNamedMy/stylix/assets/28959268/00ba9b23-c7eb-4cbf-9f3d-aa8de159d6dd)
Example of a modified systemd logo. The square brackets are using the main color,
which is usually be white or black depending on the polarity of the scheme.
## Text Editors/Viewers
Text editors are any application that can view or edit source code.
Examples include vim, helix, and bat.
For these please refer to the official
[base16 style guide](https://github.com/chriskempson/base16/blob/main/styling.md).

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

83
docs/src/testbeds.md Normal file
View File

@ -0,0 +1,83 @@
# Testbeds
Stylix provides a suite of virtual machines which can be used to test and
preview themes without installing the target to your live system.
These can be particularly helpful for:
- Working on targets before the login screen, since you can avoid closing
your editor to see the result.
- Developing for a different desktop environment than the one you normally use.
- Reducing the risk of breaking your system while reviewing pull requests.
Testbeds are also built by GitHub Actions for every pull request. This is less
beneficial compared to running them yourself, since it cannot visually check
the theme, however it can catch build failures which may have been missed
otherwise.
## Creation
New testbeds are defined by creating a file called `testbed.nix` within the
folder for the corresponding target. This file will automatically be loaded
as a NixOS module, with options such as `stylix.image` already defined.
The module should include any options necessary to install the target and
any supporting software - for example, a window manager.
If the target can only be used through Home Manager, you can write a
Home Manager module within the NixOS module using the following format:
```nix
{
home-manager.sharedModules = [{
# Write Home Manager options here
}];
}
```
Using `home-manager.sharedModules` is preferred over `home-manager.users.guest`
since it allows us to easily change the username or add additional users in
the future.
Once the module is complete, use `git add` to track the file, then the new
packages will be [available to use](#usage).
## Usage
You can list the available testbeds by running this command from anywhere
within the repository:
```console
user@host:~$ nix flake show
github:danth/stylix
└───packages
└───x86_64-linux
├───docs: package 'stylix-book'
├───palette-generator: package 'palette-generator'
├───testbed-gnome-dark: package 'testbed-gnome-dark'
├───testbed-gnome-light: package 'testbed-gnome-light'
├───testbed-kde-dark: package 'testbed-kde-dark'
└───testbed-kde-light: package 'testbed-kde-light'
```
(This has been edited down to only the relevant parts.)
To start a testbed, each of which is named in the format
`testbed-«target»-«polarity»`, run the following command:
```console
user@host:~$ nix run .#testbed-«target»-«polarity»
```
Any package with a name not fitting the given format is not a testbed,
and may behave differently with this command, or not work at all.
Once the virtual machine starts, a window should open, similar to the screenshot
below. The contents of the virtual machine will vary depending on the target you
selected earlier.
![GDM login screen with a dark background color and showing a guest user](testbed-gnome-dark.png)
If the testbed includes a login screen, the guest user should log in
automatically when selected. Depending on the software used, you may still be
presented with a password prompt - in which case you can leave it blank and
proceed by pressing enter.

81
docs/src/tricks.md Normal file
View File

@ -0,0 +1,81 @@
# Tips and tricks
## Adjusting the brightness and contrast of a background image
If you want to use a background image for your desktop but find it too bright or distracting, you can use the `imagemagick` package to dim the image, or adjust its brightness and contrast to suit your preference.
Here's an example Nix expression that takes an input image, applies a brightness/contrast adjustment to it, and saves the result as a new image file:
```nix
{ pkgs, ... }:
let
inputImage = ./path/to/image.jpg;
brightness = -30;
contrast = 0;
fillColor = "black"
in
{
stylix.image = pkgs.runCommand "dimmed-background.png" { } ''
${pkgs.imagemagick}/bin/convert "${inputImage}" -brightness-contrast ${brightness},${contrast} -fill ${fillColor} $out
'';
}
```
## Dynamic wallpaper generation based on selected theme
With imagemagick, you can also dynamically generate wallpapers based on the selected theme.
Similarly, you can use a template image and repaint it for the current theme.
```nix
{ pkgs, ... }:
let
theme = "${pkgs.base16-schemes}/share/themes/catppuccin-latte.yaml";
wallpaper = pkgs.runCommand "image.png" {} ''
COLOR=$(${pkgs.yq}/bin/yq -r .base00 ${theme})
COLOR="#"$COLOR
${pkgs.imagemagick}/bin/magick convert -size 1920x1080 xc:$COLOR $out
'';
in {
stylix = {
image = wallpaper;
base16Scheme = theme;
};
}
```
Which is neatly implemented as a single function in `lib.stylix.pixel`:
```nix
{ pkgs, config, ... }:
{
stylix = {
image = config.lib.stylix.pixel "base0A";
base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-latte.yaml";
};
}
```
## Completely disabling some stylix targets
Nixpkgs module system sometimes works in non-intuitive ways, e.g. parts
of the configuration guarded by `lib.mkIf` are still being descended
into. This means that every **loaded** (and not enabled) module must
be compatible with others - in the sense that **every** option that is
mentioned in the disabled parts of the configuration still needs to be
defined somewhere.
Sometimes that can be a problem, when your particular configuration
diverges enough from what stylix expects. In that case you can try
stubbing all the missing options in your configuration.
Or in a much clearer fashion you can just disable offending stylix targets
by adding the following `disableModules` line next to importing stylix
itself:
```nix
imports = [ flake.inputs.stylix.nixosModules.stylix ];
disabledModules = [ "${flake.inputs.stylix}/modules/<some-module>/nixos.nix" ];
```

259
flake.lock Normal file
View File

@ -0,0 +1,259 @@
{
"nodes": {
"base16": {
"inputs": {
"fromYaml": "fromYaml"
},
"locked": {
"lastModified": 1732200724,
"narHash": "sha256-+R1BH5wHhfnycySb7Sy5KbYEaTJZWm1h+LW1OtyhiTs=",
"owner": "SenchoPens",
"repo": "base16.nix",
"rev": "153d52373b0fb2d343592871009a286ec8837aec",
"type": "github"
},
"original": {
"owner": "SenchoPens",
"repo": "base16.nix",
"type": "github"
}
},
"base16-fish": {
"flake": false,
"locked": {
"lastModified": 1622559957,
"narHash": "sha256-PebymhVYbL8trDVVXxCvZgc0S5VxI7I1Hv4RMSquTpA=",
"owner": "tomyun",
"repo": "base16-fish",
"rev": "2f6dd973a9075dabccd26f1cded09508180bf5fe",
"type": "github"
},
"original": {
"owner": "tomyun",
"repo": "base16-fish",
"type": "github"
}
},
"base16-helix": {
"flake": false,
"locked": {
"lastModified": 1725860795,
"narHash": "sha256-Z2o8VBPW3I+KKTSfe25kskz0EUj7MpUh8u355Z1nVsU=",
"owner": "tinted-theming",
"repo": "base16-helix",
"rev": "7f795bf75d38e0eea9fed287264067ca187b88a9",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-helix",
"type": "github"
}
},
"base16-vim": {
"flake": false,
"locked": {
"lastModified": 1731949548,
"narHash": "sha256-XIDexXM66sSh5j/x70e054BnUsviibUShW7XhbDGhYo=",
"owner": "tinted-theming",
"repo": "base16-vim",
"rev": "61165b1632409bd55e530f3dbdd4477f011cadc6",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-vim",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"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"
}
},
"fromYaml": {
"flake": false,
"locked": {
"lastModified": 1731966426,
"narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=",
"owner": "SenchoPens",
"repo": "fromYaml",
"rev": "106af9e2f715e2d828df706c386a685698f3223b",
"type": "github"
},
"original": {
"owner": "SenchoPens",
"repo": "fromYaml",
"type": "github"
}
},
"gnome-shell": {
"flake": false,
"locked": {
"lastModified": 1732369855,
"narHash": "sha256-JhUWbcYPjHO3Xs3x9/Z9RuqXbcp5yhPluGjwsdE2GMg=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "dadd58f630eeea41d645ee225a63f719390829dc",
"type": "github"
},
"original": {
"owner": "GNOME",
"ref": "47.2",
"repo": "gnome-shell",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1733085484,
"narHash": "sha256-dVmNuUajnU18oHzBQWZm1BQtANCHaqNuxTHZQ+GN0r8=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "c1fee8d4a60b89cae12b288ba9dbc608ff298163",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1732238832,
"narHash": "sha256-sQxuJm8rHY20xq6Ah+GwIUkF95tWjGRd1X8xF+Pkk38=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "8edf06bea5bcbee082df1b7369ff973b91618b8d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"base16": "base16",
"base16-fish": "base16-fish",
"base16-helix": "base16-helix",
"base16-vim": "base16-vim",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"gnome-shell": "gnome-shell",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
"systems": "systems",
"tinted-foot": "tinted-foot",
"tinted-kitty": "tinted-kitty",
"tinted-tmux": "tinted-tmux"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"tinted-foot": {
"flake": false,
"locked": {
"lastModified": 1726913040,
"narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=",
"owner": "tinted-theming",
"repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github"
}
},
"tinted-kitty": {
"flake": false,
"locked": {
"lastModified": 1716423189,
"narHash": "sha256-2xF3sH7UIwegn+2gKzMpFi3pk5DlIlM18+vj17Uf82U=",
"owner": "tinted-theming",
"repo": "tinted-kitty",
"rev": "eb39e141db14baef052893285df9f266df041ff8",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-kitty",
"rev": "eb39e141db14baef052893285df9f266df041ff8",
"type": "github"
}
},
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1729501581,
"narHash": "sha256-1ohEFMC23elnl39kxWnjzH1l2DFWWx4DhFNNYDTYt54=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "f0e7f7974a6441033eb0a172a0342e96722b4f14",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-tmux",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

134
flake.nix Normal file
View File

@ -0,0 +1,134 @@
{
inputs = {
base16-fish = {
flake = false;
url = "github:tomyun/base16-fish";
};
base16-helix = {
flake = false;
url = "github:tinted-theming/base16-helix";
};
base16-vim = {
flake = false;
url = "github:tinted-theming/base16-vim";
};
base16.url = "github:SenchoPens/base16.nix";
flake-compat = {
flake = false;
url = "github:edolstra/flake-compat";
};
flake-utils = {
inputs.systems.follows = "systems";
url = "github:numtide/flake-utils";
};
gnome-shell = {
flake = false;
# TODO: Unlocking the input and pointing to official repository requires
# updating the patch:
# https://github.com/danth/stylix/pull/224#discussion_r1460339607.
url = "github:GNOME/gnome-shell/47.2";
};
# The 'home-manager' input is used to generate the documentation.
home-manager = {
inputs.nixpkgs.follows = "nixpkgs";
url = "github:nix-community/home-manager";
};
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
# Interface flake systems.
systems.url = "github:nix-systems/default";
tinted-foot = {
flake = false;
# Lock the tinted-foot input to prevent upstream breaking changes.
#
# Considering that Stylix eventually re-implements this input's
# functionality [1], it might be easiest to lock this input to avoid
# wasted maintenance effort.
#
# [1]: https://github.com/danth/stylix/issues/571
url = "github:tinted-theming/tinted-foot/fd1b924b6c45c3e4465e8a849e67ea82933fcbe4";
};
tinted-tmux = {
flake = false;
url = "github:tinted-theming/tinted-tmux";
};
tinted-kitty = {
flake = false;
# Lock the tinted-kitty input to prevent upstream breaking changes.
#
# Considering that Stylix eventually re-implements this input's
# functionality [1], it might be easiest to lock this input to avoid
# wasted maintenance effort.
#
# [1]: https://github.com/danth/stylix/issues/534
url = "github:tinted-theming/tinted-kitty/eb39e141db14baef052893285df9f266df041ff8";
};
};
outputs =
{ nixpkgs, base16, self, ... }@inputs:
inputs.flake-utils.lib.eachDefaultSystem (
system: let
inherit (nixpkgs) lib;
pkgs = nixpkgs.legacyPackages.${system};
in {
packages = let
universalPackages = {
docs = import ./docs { inherit pkgs inputs lib; };
palette-generator = pkgs.callPackage ./palette-generator { };
};
# Testbeds are virtual machines based on NixOS, therefore they are
# only available for Linux systems.
testbedPackages = lib.optionalAttrs
(lib.hasSuffix "-linux" system)
(import ./stylix/testbed.nix { inherit pkgs inputs lib; });
in
universalPackages // testbedPackages;
}
)
// {
nixosModules.stylix = { pkgs, ... }@args: {
imports = [
(import ./stylix/nixos inputs {
inherit (self.packages.${pkgs.system}) palette-generator;
base16 = base16.lib args;
homeManagerModule = self.homeManagerModules.stylix;
})
];
};
homeManagerModules.stylix = { pkgs, ... }@args: {
imports = [
(import ./stylix/hm inputs {
inherit (self.packages.${pkgs.system}) palette-generator;
base16 = base16.lib args;
})
];
};
darwinModules.stylix = { pkgs, ... }@args: {
imports = [
(import ./stylix/darwin inputs {
inherit (self.packages.${pkgs.system}) palette-generator;
base16 = base16.lib args;
homeManagerModule = self.homeManagerModules.stylix;
})
];
};
};
}

BIN
gnome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 KiB

BIN
kde.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 KiB

54
modules/alacritty/hm.nix Normal file
View File

@ -0,0 +1,54 @@
# Documentation is available at:
# - https://alacritty.org/config-alacritty.html
# - `man 5 alacritty`
{ config, lib, ... }:
let
colors = config.lib.stylix.colors.withHashtag;
in
{
options.stylix.targets.alacritty.enable = config.lib.stylix.mkEnableTarget "Alacritty" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.alacritty.enable) {
programs.alacritty.settings = {
font = with config.stylix.fonts; {
normal = {
family = monospace.name;
style = "Regular";
};
size = sizes.terminal;
};
window.opacity = with config.stylix.opacity; terminal;
colors = with colors; {
primary = {
foreground = base05;
background = base00;
bright_foreground = base07;
};
selection = {
text = base05;
background = base02;
};
cursor = {
text = base00;
cursor = base05;
};
normal = {
black = base00;
white = base05;
inherit red green yellow blue magenta cyan;
};
bright = {
black = base03;
white = base07;
red = bright-red;
green = bright-green;
inherit yellow;
blue = bright-blue;
magenta = bright-magenta;
cyan = bright-cyan;
};
};
};
};
}

26
modules/avizo/hm.nix Normal file
View File

@ -0,0 +1,26 @@
{ config, lib, options, ... }:
with config.lib.stylix.colors;
with config.stylix.fonts;
let
aviOpacity = toString config.stylix.opacity.popups;
in
{
options.stylix.targets.avizo.enable =
config.lib.stylix.mkEnableTarget "Avizo" true;
# Referenced https://github.com/stacyharper/base16-mako
config = lib.optionalAttrs (options.services ? avizo) (lib.mkIf (config.stylix.enable && config.stylix.targets.avizo.enable) {
services.avizo = {
settings = {
default = {
background = "rgba(${base01-rgb-r}, ${base01-rgb-g}, ${base01-rgb-b}, ${aviOpacity})";
border-color = "rgba(${base0D-rgb-r}, ${base0D-rgb-g}, ${base0D-rgb-b}, ${aviOpacity})";
bar-fg-color = "rgba(${base05-rgb-r}, ${base05-rgb-g}, ${base05-rgb-b}, ${aviOpacity})";
bar-bg-color = "rgba(${base01-rgb-r}, ${base01-rgb-g}, ${base01-rgb-b}, ${aviOpacity})";
image-opacity = aviOpacity;
};
};
};
});
}

View File

@ -0,0 +1,538 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>author</key>
<string>Template: Chris Kempson, Scheme: Mitchell Kember</string>
<key>name</key>
<string>Base16 Stylix</string>
<key>colorSpaceName</key>
<string>sRGB</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>background</key>
<string>#{{base00-hex}}</string>
<key>caret</key>
<string>#{{base05-hex}}</string>
<key>foreground</key>
<string>#{{base05-hex}}</string>
<key>invisibles</key>
<string>#{{base03-hex}}</string>
<key>lineHighlight</key>
<string>#{{base03-hex}}</string>
<key>selection</key>
<string>#{{base02-hex}}</string>
<key>gutter</key>
<string>#{{base01-hex}}</string>
<key>gutterForeground</key>
<string>#{{base03-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Text</string>
<key>scope</key>
<string>variable.parameter.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base05-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comments</string>
<key>scope</key>
<string>comment, punctuation.definition.comment</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base03-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Punctuation</string>
<key>scope</key>
<string>punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base05-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Delimiters</string>
<key>scope</key>
<string>none</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base05-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Operators</string>
<key>scope</key>
<string>keyword.operator</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base05-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keywords</string>
<key>scope</key>
<string>keyword</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0E-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variables</string>
<key>scope</key>
<string>variable</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base05-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Functions</string>
<key>scope</key>
<string>entity.name.function, meta.require, support.function.any-method</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0D-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Labels</string>
<key>scope</key>
<string>entity.name.label</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0F-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Classes</string>
<key>scope</key>
<string>support.class, entity.name.class, entity.name.type.class, entity.name</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0A-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Classes</string>
<key>scope</key>
<string>meta.class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base07-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Methods</string>
<key>scope</key>
<string>keyword.other.special-method</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0D-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Storage</string>
<key>scope</key>
<string>storage</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0E-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Support</string>
<key>scope</key>
<string>support.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0C-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Strings, Inherited Class</string>
<key>scope</key>
<string>string, constant.other.symbol, entity.other.inherited-class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0B-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Integers</string>
<key>scope</key>
<string>constant.numeric</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Floats</string>
<key>scope</key>
<string>none</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Boolean</string>
<key>scope</key>
<string>none</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Constants</string>
<key>scope</key>
<string>constant</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Tags</string>
<key>scope</key>
<string>entity.name.tag</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base08-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Attributes</string>
<key>scope</key>
<string>entity.other.attribute-name</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Attribute IDs</string>
<key>scope</key>
<string>entity.other.attribute-name.id, punctuation.definition.entity</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0D-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Selector</string>
<key>scope</key>
<string>meta.selector</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0E-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Values</string>
<key>scope</key>
<string>none</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Headings</string>
<key>scope</key>
<string>markup.heading, punctuation.definition.heading, entity.name.section</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#{{base0D-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Units</string>
<key>scope</key>
<string>keyword.other.unit</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Bold</string>
<key>scope</key>
<string>markup.bold, punctuation.definition.bold</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>bold</string>
<key>foreground</key>
<string>#{{base0A-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Italic</string>
<key>scope</key>
<string>markup.italic, punctuation.definition.italic</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>italic</string>
<key>foreground</key>
<string>#{{base0E-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Code</string>
<key>scope</key>
<string>markup.raw.inline</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0B-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Link Text</string>
<key>scope</key>
<string>string.other.link, punctuation.definition.string.end.markdown, punctuation.definition.string.begin.markdown</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base08-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Link Url</string>
<key>scope</key>
<string>meta.link</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Quotes</string>
<key>scope</key>
<string>markup.quote</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base09-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Separator</string>
<key>scope</key>
<string>meta.separator</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#{{base02-hex}}</string>
<key>foreground</key>
<string>#{{base05-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Inserted</string>
<key>scope</key>
<string>markup.inserted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0B-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Deleted</string>
<key>scope</key>
<string>markup.deleted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base08-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Changed</string>
<key>scope</key>
<string>markup.changed</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0E-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Colors</string>
<key>scope</key>
<string>constant.other.color</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0C-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Regular Expressions</string>
<key>scope</key>
<string>string.regexp</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0C-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Escape Characters</string>
<key>scope</key>
<string>constant.character.escape</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0C-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Embedded</string>
<key>scope</key>
<string>punctuation.section.embedded, variable.interpolation</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#{{base0E-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Illegal</string>
<key>scope</key>
<string>invalid.illegal</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#{{base08-hex}}</string>
<key>foreground</key>
<string>#{{base07-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Broken</string>
<key>scope</key>
<string>invalid.broken</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#{{base09-hex}}</string>
<key>foreground</key>
<string>#{{base00-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Deprecated</string>
<key>scope</key>
<string>invalid.deprecated</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#{{base0F-hex}}</string>
<key>foreground</key>
<string>#{{base07-hex}}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Unimplemented</string>
<key>scope</key>
<string>invalid.unimplemented</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#{{base03-hex}}</string>
<key>foreground</key>
<string>#{{base07-hex}}</string>
</dict>
</dict>
</array>
<key>uuid</key>
<string>uuid</string>
</dict>
</plist>

19
modules/bat/hm.nix Normal file
View File

@ -0,0 +1,19 @@
{ config, lib, ... }:
{
options.stylix.targets.bat.enable =
config.lib.stylix.mkEnableTarget "Bat" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.bat.enable) {
programs.bat = {
# This theme is reused for yazi. Changes to the template
# will need to be applied to modules/yazi/hm.nix
themes."base16-stylix".src = config.lib.stylix.colors {
template = ./base16-stylix.mustache;
extension = ".tmTheme";
};
config.theme = "base16-stylix";
};
};
}

51
modules/bemenu/hm.nix Normal file
View File

@ -0,0 +1,51 @@
{ config, lib, ... }:
with config.lib.stylix.colors.withHashtag;
with config.stylix.fonts;
let
bemenuOpacity = lib.toHexString (((builtins.ceil (config.stylix.opacity.popups * 100)) * 255) / 100);
in {
options.stylix.targets.bemenu = {
enable = config.lib.stylix.mkEnableTarget "bemenu" true;
fontSize = lib.mkOption {
description = ''
Font size used for bemenu.
'';
type = with lib.types; nullOr int;
default = sizes.popups;
}; # optional argument
alternate = lib.mkOption {
description = ''
Whether to use alternating colours.
'';
type = lib.types.bool;
default = false;
};
};
config = lib.mkIf (config.stylix.enable && config.stylix.targets.bemenu.enable) {
programs.bemenu.settings = with config.stylix.targets.bemenu; {
tb = "${base01}${bemenuOpacity}"; # Title bg
nb = "${base01}${bemenuOpacity}"; # Normal bg
fb = "${base01}${bemenuOpacity}"; # Filter bg
hb = "${base03}${bemenuOpacity}"; # Highlighted bg
sb = "${base03}${bemenuOpacity}"; # Selected bg
scb = "${base01}"; # Scrollbar bg
hf = "${base0A}"; # Highlighted fg
sf = "${base0B}"; # Selected fg
tf = "${base05}"; # Title fg
ff = "${base05}"; # Filter fg
nf = "${base05}"; # Normal fg
scf = "${base03}"; # Scrollbar fg
ab = "${if alternate then base00 else base01}"; # Alternate bg
af = "${if alternate then base04 else base05}"; # Alternate fg
# Font name
fn = "${sansSerif.name} ${lib.optionalString (fontSize != null) (builtins.toString fontSize)}";
};
};
}

17
modules/bspwm/hm.nix Normal file
View File

@ -0,0 +1,17 @@
{ config, lib, ... }:
let
colors = config.lib.stylix.colors.withHashtag;
in {
options.stylix.targets.bspwm.enable =
config.lib.stylix.mkEnableTarget "bspwm" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.bspwm.enable) {
xsession.windowManager.bspwm.settings = {
normal_border_color = colors.base03;
active_border_color = colors.base0C;
focused_border_color = colors.base0D;
presel_feedback_color = colors.base00;
};
};
}

61
modules/btop/hm.nix Normal file
View File

@ -0,0 +1,61 @@
{ config, lib, ... }:
let
colors = config.lib.stylix.colors.withHashtag;
in {
options.stylix.targets.btop.enable = config.lib.stylix.mkEnableTarget "btop" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.btop.enable && config.programs.btop.enable) {
programs.btop.settings = {
color_theme = "stylix";
theme_background = lib.mkIf (config.stylix.opacity.terminal != 1.0) false;
};
xdg.configFile."btop/themes/stylix.theme".text = with colors; ''
#Generated by Stylix
theme[main_bg]="${base00}"
theme[main_fg]="${base05}"
theme[title]="${base05}"
theme[hi_fg]="${base0D}"
theme[selected_bg]="${base03}"
theme[selected_fg]="${base0D}"
theme[inactive_fg]="${base04}"
theme[graph_text]="${base06}"
theme[meter_bg]="${base03}"
theme[proc_misc]="${base06}"
theme[cpu_box]="${base0E}"
theme[mem_box]="${base0B}"
theme[net_box]="${base0C}"
theme[proc_box]="${base0D}"
theme[div_line]="${base01}"
theme[temp_start]="${base0B}"
theme[temp_mid]="${base0A}"
theme[temp_end]="${base08}"
theme[cpu_start]="${base0B}"
theme[cpu_mid]="${base0A}"
theme[cpu_end]="${base08}"
theme[free_start]="${base0B}"
theme[free_mid]="${base0A}"
theme[free_end]="${base08}"
theme[cached_start]="${base0B}"
theme[cached_mid]="${base0A}"
theme[cached_end]="${base08}"
theme[available_start]="${base0B}"
theme[available_mid]="${base0A}"
theme[available_end]="${base08}"
theme[used_start]="${base0B}"
theme[used_mid]="${base0A}"
theme[used_end]="${base08}"
theme[download_start]="${base0B}"
theme[download_mid]="${base0A}"
theme[download_end]="${base08}"
theme[upload_start]="${base0B}"
theme[upload_mid]="${base0A}"
theme[upload_end]="${base08}"
theme[process_start]="${base0B}"
theme[process_mid]="${base0A}"
theme[process_end]="${base08}"
'';
};
}

34
modules/cava/hm.nix Normal file
View File

@ -0,0 +1,34 @@
{ config, lib, ... }:
let
mkGradient = colors: lib.listToAttrs (lib.imap0 (i: c: lib.nameValuePair "gradient_color_${toString (i+1)}" "'#${c}'") colors) // {
gradient = 1;
gradient_count = builtins.length colors;
};
rainbowColors = with config.lib.stylix.colors; [
base0E
base0D
base0C
base0B
base0A
base09
base08
];
in {
options.stylix.targets.cava = {
enable = config.lib.stylix.mkEnableTarget "CAVA" true;
rainbow.enable = config.lib.stylix.mkEnableTarget "rainbow gradient theming" false;
};
config = let
cfg = config.stylix.targets.cava;
in
lib.mkIf (config.stylix.enable && cfg.enable) {
programs.cava.settings.color = lib.mkIf cfg.rainbow.enable (
mkGradient rainbowColors
);
};
}

View File

@ -0,0 +1,14 @@
{ config, lib, ... }:
{
options.stylix.targets.chromium.enable =
config.lib.stylix.mkEnableTarget "Chromium, Google Chrome and Brave" true;
config.programs.chromium = lib.mkIf (config.stylix.enable && config.stylix.targets.chromium.enable) {
# This enables policies without installing the browser. Policies take up a
# negligible amount of space, so it's reasonable to have this always on.
enable = true;
extraOpts.BrowserThemeColor = config.lib.stylix.colors.withHashtag.base00;
};
}

27
modules/console/nixos.nix Normal file
View File

@ -0,0 +1,27 @@
{ config, lib, ... }:
with config.lib.stylix.colors;
{
options.stylix.targets.console.enable =
config.lib.stylix.mkEnableTarget "the Linux kernel console" true;
config.console.colors = lib.mkIf (config.stylix.enable && config.stylix.targets.console.enable) [
base00-hex
red
green
yellow
blue
magenta
cyan
base05-hex
base03-hex
red
green
yellow
blue
magenta
cyan
base06-hex
];
}

37
modules/dunst/hm.nix Normal file
View File

@ -0,0 +1,37 @@
{ config, lib, ... }:
with config.lib.stylix.colors.withHashtag;
with config.stylix.fonts;
let
dunstOpacity = lib.toHexString (((builtins.ceil (config.stylix.opacity.popups * 100)) * 255) / 100);
in {
options.stylix.targets.dunst.enable =
config.lib.stylix.mkEnableTarget "Dunst" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.dunst.enable) {
services.dunst.settings = {
global = {
separator_color = base02;
font = "${sansSerif.name} ${toString sizes.popups}";
};
urgency_low = {
background = base01 + dunstOpacity;
foreground = base05;
frame_color = base0B;
};
urgency_normal = {
background = base01 + dunstOpacity;
foreground = base05;
frame_color = base0E;
};
urgency_critical = {
background = base01 + dunstOpacity;
foreground = base05;
frame_color = base08;
};
};
};
}

77
modules/emacs/hm.nix Normal file
View File

@ -0,0 +1,77 @@
{ pkgs, config, lib, ... }:
with config.lib.stylix.colors.withHashtag;
with config.stylix.fonts;
let
emacsOpacity = builtins.toString (builtins.ceil (config.stylix.opacity.applications * 100));
emacsSize = builtins.toString (sizes.terminal * 1.0);
in
{
options.stylix.targets.emacs.enable =
config.lib.stylix.mkEnableTarget "Emacs" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.emacs.enable) {
programs.emacs = {
extraPackages = epkgs:
[
(epkgs.trivialBuild {
pname = "base16-stylix-theme";
version = "0.1.0";
src = pkgs.writeText "base16-stylix-theme.el" ''
(require 'base16-theme)
(defvar base16-stylix-theme-colors
'(:base00 "${base00}"
:base01 "${base01}"
:base02 "${base02}"
:base03 "${base03}"
:base04 "${base04}"
:base05 "${base05}"
:base06 "${base06}"
:base07 "${base07}"
:base08 "${base08}"
:base09 "${base09}"
:base0A "${base0A}"
:base0B "${base0B}"
:base0C "${base0C}"
:base0D "${base0D}"
:base0E "${base0E}"
:base0F "${base0F}")
"All colors for Base16 stylix are defined here.")
;; Define the theme
(deftheme base16-stylix)
;; Add all the faces to the theme
(base16-theme-define 'base16-stylix base16-stylix-theme-colors)
;; Mark the theme as provided
(provide-theme 'base16-stylix)
;; Add path to theme to theme-path
(add-to-list 'custom-theme-load-path
(file-name-directory
(file-truename load-file-name)))
(provide 'base16-stylix-theme)
'';
packageRequires = [ epkgs.base16-theme ];
})
];
extraConfig = ''
;; ---- Generated by stylix ----
(require 'base16-stylix-theme)
(setq base16-theme-256-color-source 'colors)
(load-theme 'base16-stylix t)
;; Set font
(set-face-attribute 'default nil :font (font-spec :family "${monospace.name}" :size ${emacsSize}))
;; -----------------------------
;; set opacity
(add-to-list 'default-frame-alist '(alpha-background . ${emacsOpacity}))
;; -----------------------------
'';
};
};
}

35
modules/feh/hm.nix Normal file
View File

@ -0,0 +1,35 @@
{ pkgs, config, lib, ... }:
{
options.stylix.targets.feh.enable =
config.lib.stylix.mkEnableTarget
"the desktop background using Feh"
true;
config.xsession.initExtra =
lib.mkIf (
config.stylix.enable
&& config.stylix.targets.feh.enable
&& (
with config.xsession.windowManager;
bspwm.enable
|| herbstluftwm.enable
|| i3.enable
|| spectrwm.enable
|| xmonad.enable
)
) (let
inherit (config.stylix) imageScalingMode;
bg-arg =
if imageScalingMode == "fill"
then "--bg-fill"
else if imageScalingMode == "center"
then "--bg-center"
else if imageScalingMode == "tile"
then "--bg-tile"
else if imageScalingMode == "stretch"
then "--bg-scale"
# Fit
else "--bg-max";
in "${pkgs.feh}/bin/feh --no-fehbg ${bg-arg} ${config.stylix.image}");
}

33
modules/feh/nixos.nix Normal file
View File

@ -0,0 +1,33 @@
{ pkgs, config, lib, ... }:
{
options.stylix.targets.feh.enable =
config.lib.stylix.mkEnableTarget
"the desktop background using Feh"
true;
config.services.xserver.displayManager.sessionCommands =
lib.mkIf (
config.stylix.enable
&& config.stylix.targets.feh.enable
&& (
with config.services.xserver.windowManager;
xmonad.enable
|| i3.enable
)
)
(let
inherit (config.stylix) imageScalingMode;
bg-arg =
if imageScalingMode == "fill"
then "--bg-fill"
else if imageScalingMode == "center"
then "--bg-center"
else if imageScalingMode == "tile"
then "--bg-tile"
else if imageScalingMode == "stretch"
then "--bg-scale"
# Fit
else "--bg-max";
in "${pkgs.feh}/bin/feh --no-fehbg ${bg-arg} ${config.stylix.image}");
}

32
modules/firefox/hm.nix Normal file
View File

@ -0,0 +1,32 @@
# Consider also updating the LibreWolf module when updating this module,
# as they are very similar.
{ config, lib, ... }:
let
profileSettings = {
settings = {
"font.name.monospace.x-western" = config.stylix.fonts.monospace.name;
"font.name.sans-serif.x-western" = config.stylix.fonts.sansSerif.name;
"font.name.serif.x-western" = config.stylix.fonts.serif.name;
};
};
makeProfileSettingsPair = profileName:
lib.nameValuePair profileName profileSettings;
in {
options.stylix.targets.firefox = {
enable =
config.lib.stylix.mkEnableTarget "Firefox" true;
profileNames = lib.mkOption {
description = "The Firefox profile names to apply styling on.";
type = lib.types.listOf lib.types.str;
default = [ ];
};
};
config = lib.mkIf (config.stylix.enable && config.stylix.targets.firefox.enable) {
programs.firefox.profiles = lib.listToAttrs
(map makeProfileSettingsPair config.stylix.targets.firefox.profileNames);
};
}

10
modules/fish/hm.nix Normal file
View File

@ -0,0 +1,10 @@
{ config, lib, ... }:
{
options.stylix.targets.fish.enable =
config.lib.stylix.mkEnableTarget "Fish" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.fish.enable) {
programs.fish.interactiveShellInit = import ./prompt.nix config;
};
}

10
modules/fish/nixos.nix Normal file
View File

@ -0,0 +1,10 @@
{ config, lib, ... }:
{
options.stylix.targets.fish.enable =
config.lib.stylix.mkEnableTarget "Fish" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.fish.enable) {
programs.fish.promptInit = import ./prompt.nix config;
};
}

14
modules/fish/prompt.nix Normal file
View File

@ -0,0 +1,14 @@
config:
let
theme = config.lib.stylix.colors {
templateRepo = config.lib.stylix.templates.base16-fish;
};
in ''
source ${theme}
# See https://github.com/tomyun/base16-fish/issues/7 for why this condition exists
if status --is-interactive && test -z "$TMUX"
base16-${config.lib.stylix.colors.slug}
end
''

24
modules/foot/hm.nix Normal file
View File

@ -0,0 +1,24 @@
{ config, lib, ... }:
let
cfg = config.stylix.targets.foot;
theme = config.lib.stylix.colors {
templateRepo = config.lib.stylix.templates.tinted-foot;
};
in {
options.stylix.targets.foot.enable =
config.lib.stylix.mkEnableTarget "Foot" true;
config.programs.foot.settings = lib.mkIf cfg.enable {
main = {
include = theme;
font =
with config.stylix.fonts;
"${monospace.name}:size=${toString sizes.terminal}";
dpi-aware = "no";
};
colors.alpha = with config.stylix.opacity; terminal;
};
}

13
modules/forge/hm.nix Normal file
View File

@ -0,0 +1,13 @@
{ config, lib, ... }:
{
options.stylix.targets.forge.enable =
config.lib.stylix.mkEnableTarget "Forge" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.forge.enable) {
xdg.configFile."forge/stylesheet/forge/stylesheet.css".source = config.lib.stylix.colors {
template = ./stylesheet.css.mustache;
extension = ".css";
};
};
}

View File

@ -0,0 +1,140 @@
.tiled {
color: #{{base0D-hex}};
opacity: 1;
border-width: 3px;
}
.split {
color: #{{base0D-hex}};
opacity: 1;
border-width: 3px;
}
.stacked {
color: #{{base0D-hex}};
opacity: 1;
border-width: 3px;
}
.tabbed {
color: #{{base0D-hex}};
opacity: 1;
border-width: 3px;
}
.floated {
color: #{{base0D-hex}};
border-width: 3px;
opacity: 1;
}
.window-tiled-border {
border-width: 3px;
border-color: #{{base0D-hex}};
border-style: solid;
border-radius: 14px;
}
.window-split-border {
border-width: 3px;
border-color: #{{base0D-hex}};
border-style: solid;
border-radius: 14px;
}
.window-split-horizontal {
border-left-width: 0;
border-top-width: 0;
border-bottom-width: 0;
}
.window-split-vertical {
border-left-width: 0;
border-top-width: 0;
border-right-width: 0;
}
.window-stacked-border {
border-width: 3px;
border-color: #{{base0D-hex}};
border-style: solid;
border-radius: 14px;
}
.window-tabbed-border {
border-width: 3px;
border-color: #{{base0D-hex}};
border-style: solid;
border-radius: 14px;
}
.window-tabbed-bg {
border-radius: 8px;
}
.window-tabbed-tab {
background-color: rgba(54, 47, 45, 1);
border-color: #{{base0D-hex}}9A;
border-width: 1px;
border-radius: 8px;
color: white;
margin: 1px;
box-shadow: 0 0 0 1px rgba(1px 0, 0, 0, 0.2);
}
.window-tabbed-tab-active {
background-color: #{{base0D-hex}};
color: black;
box-shadow: 0 0 0 1px rgba(1px 0, 0, 0, 0.2);
}
.window-tabbed-tab-close {
padding: 3px;
margin: 4px;
border-radius: 16px;
width: 16px;
background-color: #{{base08-hex}};
}
.window-tabbed-tab-icon {
margin: 3px;
}
.window-floated-border {
border-width: 3px;
border-color: #{{base0D-hex}};
border-style: solid;
border-radius: 14px;
}
.window-tilepreview-tiled {
border-width: 1px;
border-color: #{{base0D-hex}}4D;
border-style: solid;
border-radius: 14px;
background-color: #{{base0D-hex}}33;
}
.window-tilepreview-stacked {
border-width: 1px;
border-color: #{{base0D-hex}}66;
border-style: solid;
border-radius: 14px;
background-color: #{{base0D-hex}}4D;
}
.window-tilepreview-swap {
border-width: 1px;
border-color: #{{base0D-hex}}4D;
border-style: solid;
border-radius: 14px;
background-color: #{{base0D-hex}}4D;
}
.window-tilepreview-tabbed {
border-width: 1px;
border-color: #{{base0D-hex}}4D;
border-style: solid;
border-radius: 14px;
background-color: #{{base0D-hex}}4D;
}

32
modules/fuzzel/hm.nix Normal file
View File

@ -0,0 +1,32 @@
{ config, lib, ... }:
with config.lib.stylix.colors;
let
opacity = lib.toHexString (builtins.ceil (config.stylix.opacity.popups * 255));
in {
options.stylix.targets.fuzzel.enable =
config.lib.stylix.mkEnableTarget "Fuzzel" true;
config.programs.fuzzel.settings =
lib.mkIf (config.stylix.enable && config.stylix.targets.fuzzel.enable) {
colors = {
background = "${base00-hex}${opacity}";
text = "${base05-hex}ff";
placeholder = "${base03-hex}ff";
prompt = "${base05-hex}ff";
input = "${base05-hex}ff";
match = "${base0A-hex}ff";
selection = "${base03-hex}ff";
selection-text = "${base05-hex}ff";
selection-match = "${base0A-hex}ff";
counter = "${base06-hex}ff";
border = "${base0D-hex}ff";
};
main = {
font = "${config.stylix.fonts.sansSerif.name}:size=${toString config.stylix.fonts.sizes.popups}";
};
};
}

23
modules/fzf/hm.nix Normal file
View File

@ -0,0 +1,23 @@
{ config, lib, ... }:
{
options.stylix.targets.fzf = {
enable = config.lib.stylix.mkEnableTarget "Fzf" true;
};
config = lib.mkIf (config.stylix.enable && config.stylix.targets.fzf.enable) {
programs.fzf.colors = with config.lib.stylix.colors.withHashtag; {
"bg" = base00;
"bg+" = base01;
"fg" = base04;
"fg+" = base06;
"header" = base0D;
"hl" = base0D;
"hl+" = base0D;
"info" = base0A;
"marker" = base0C;
"pointer" = base0C;
"prompt" = base0A;
"spinner" = base0C;
};
};
}

18
modules/gedit/hm.nix Normal file
View File

@ -0,0 +1,18 @@
{ config, lib, ... }:
let
style = config.lib.stylix.colors {
template = ./template.mustache;
extension = "xml";
};
in {
options.stylix.targets.gedit.enable =
config.lib.stylix.mkEnableTarget "GEdit" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.gedit.enable) {
xdg.dataFile = {
"gedit/styles/stylix.xml".source = style;
};
};
}

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<style-scheme id="stylix" _name="Stylix" version="1.0">
<author>Stylix</author>
<_description>Theme configured as part of your NixOS configuration.</_description>
<color name="base00" value="#{{base00-hex}}"/>
<color name="base01" value="#{{base01-hex}}"/>
<color name="base02" value="#{{base02-hex}}"/>
<color name="base03" value="#{{base03-hex}}"/>
<color name="base04" value="#{{base04-hex}}"/>
<color name="base05" value="#{{base05-hex}}"/>
<color name="base06" value="#{{base06-hex}}"/>
<color name="base07" value="#{{base07-hex}}"/>
<color name="base08" value="#{{base08-hex}}"/>
<color name="base09" value="#{{base09-hex}}"/>
<color name="base0A" value="#{{base0A-hex}}"/>
<color name="base0B" value="#{{base0B-hex}}"/>
<color name="base0C" value="#{{base0C-hex}}"/>
<color name="base0D" value="#{{base0D-hex}}"/>
<color name="base0E" value="#{{base0E-hex}}"/>
<color name="base0F" value="#{{base0F-hex}}"/>
<style name="bracket-match" background="base01" bold="true"/>
<style name="bracket-mismatch" background="base01" underline="true"/>
<style name="current-line" background="base01"/>
<style name="cursor" foreground="base03"/>
<style name="draw-spaces" foreground="base02"/>
<style name="line-numbers" foreground="base06" background="base01"/>
<style name="search-match" background="base01" bold="true" underline="true"/>
<style name="selection" foreground="base06" background="base02"/>
<style name="text" foreground="base06" background="base00"/>
<style name="css:at-rules" foreground="base0E"/>
<style name="css:color" foreground="base05"/>
<style name="css:keyword" foreground="base0A"/>
<style name="def:base-n-integer" foreground="base09"/>
<style name="def:boolean" foreground="base09"/>
<style name="def:builtin" foreground="base09"/>
<style name="def:character" foreground="base09"/>
<style name="def:comment" foreground="base04"/>
<style name="def:complex" foreground="base09"/>
<style name="def:decimal" foreground="base09"/>
<style name="def:doc-comment" foreground="base04"/>
<style name="def:doc-comment-element" foreground="base04"/>
<style name="def:error" foreground="base07" background="base08"/>
<style name="def:floating-point" foreground="base09"/>
<style name="def:function" foreground="base0D"/>
<style name="def:identifier" foreground="base08"/>
<style name="def:keyword" foreground="base0E"/>
<style name="def:note" foreground="base04"/>
<style name="def:number" foreground="base09"/>
<style name="def:operator" foreground="base0C"/>
<style name="def:preprocessor" foreground="base09"/>
<style name="def:reserved" foreground="base0E"/>
<style name="def:shebang" foreground="base04"/>
<style name="def:special-char" foreground="base09"/>
<style name="def:special-constant" foreground="base09"/>
<style name="def:statement" foreground="base0E"/>
<style name="def:string" foreground="base0B"/>
<style name="def:type" foreground="base0A"/>
<style name="html:dtd" foreground="base0B"/>
<style name="html:tag" foreground="base08"/>
<style name="js:function" foreground="base0D"/>
<style name="perl:builtin" foreground="base0D"/>
<style name="perl:include-statement" foreground="base0E"/>
<style name="perl:special-variable" foreground="base09"/>
<style name="perl:variable" foreground="base08"/>
<style name="php:string" foreground="base0B"/>
<style name="python:builtin-constant" foreground="base0E"/>
<style name="python:builtin-function" foreground="base0D"/>
<style name="python:module-handler" foreground="base0E"/>
<style name="python:special-variable" foreground="base0E"/>
<style name="ruby:attribute-definition" foreground="base0E"/>
<style name="ruby:builtin" foreground="base08"/>
<style name="ruby:class-variable" foreground="base08"/>
<style name="ruby:constant" foreground="base08"/>
<style name="ruby:global-variable" foreground="base0D"/>
<style name="ruby:instance-variable" foreground="base08"/>
<style name="ruby:module-handler" foreground="base0E"/>
<style name="ruby:predefined-variable" foreground="base09"/>
<style name="ruby:regex" foreground="base08"/>
<style name="ruby:special-variable" foreground="base0E"/>
<style name="ruby:symbol" foreground="base0B"/>
<style name="rubyonrails:attribute-definition" foreground="base0E"/>
<style name="rubyonrails:block-parameter" foreground="base09"/>
<style name="rubyonrails:builtin" foreground="base08"/>
<style name="rubyonrails:class-inherit" foreground="base0B"/>
<style name="rubyonrails:class-name" foreground="base0A"/>
<style name="rubyonrails:class-variable" foreground="base08"/>
<style name="rubyonrails:complex-interpolation" foreground="base09"/>
<style name="rubyonrails:constant" foreground="base08"/>
<style name="rubyonrails:global-variable" foreground="base0D"/>
<style name="rubyonrails:instance-variable" foreground="base08"/>
<style name="rubyonrails:module-handler" foreground="base0E"/>
<style name="rubyonrails:module-name" foreground="base0A"/>
<style name="rubyonrails:predefined-variable" foreground="base09"/>
<style name="rubyonrails:rails" foreground="base08"/>
<style name="rubyonrails:regex" foreground="base08"/>
<style name="rubyonrails:simple-interpolation" foreground="base09"/>
<style name="rubyonrails:special-variable" foreground="base0E"/>
<style name="rubyonrails:symbol" foreground="base0B"/>
<style name="xml:attribute-name" foreground="base08"/>
<style name="xml:doctype" foreground="base08"/>
<style name="xml:element-name" foreground="base08"/>
<style name="xml:namespace" foreground="base08"/>
<style name="xml:tag" foreground="base08"/>
</style-scheme>

44
modules/gitui/hm.nix Normal file
View File

@ -0,0 +1,44 @@
{ config, lib, ... }:
let
inherit (config.lib.stylix) colors;
mkRgb = color:
let
r = colors."${color}-rgb-r";
g = colors."${color}-rgb-g";
b = colors."${color}-rgb-b";
in
"Rgb(${r}, ${g}, ${b})";
in
{
options.stylix.targets.gitui.enable =
config.lib.stylix.mkEnableTarget "GitUI" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.gitui.enable) {
programs.gitui.theme = ''
(
selected_tab: Some(Reset),
command_fg: Some(${mkRgb "base05"}),
selection_bg: Some(${mkRgb "base04"}),
selection_fg: Some(${mkRgb "base05"}),
cmdbar_bg: Some(${mkRgb "base01"}),
cmdbar_extra_lines_bg: Some(${mkRgb "base01"}),
disabled_fg: Some(${mkRgb "base04"}),
diff_line_add: Some(${mkRgb "base0B"}),
diff_line_delete: Some(${mkRgb "base08"}),
diff_file_added: Some(${mkRgb "base0A"}),
diff_file_removed: Some(${mkRgb "base08"}),
diff_file_moved: Some(${mkRgb "base0E"}),
diff_file_modified: Some(${mkRgb "base09"}),
commit_hash: Some(${mkRgb "base07"}),
commit_time: Some(${mkRgb "base05"}),
commit_author: Some(${mkRgb "base0D"}),
danger_fg: Some(${mkRgb "base08"}),
push_gauge_bg: Some(${mkRgb "base0D"}),
push_gauge_fg: Some(${mkRgb "base00"}),
tag_fg: Some(${mkRgb "base06"}),
branch_fg: Some(${mkRgb "base0C"})
)
'';
};
}

View File

@ -0,0 +1,84 @@
// _default-colors.scss
$destructive_bg_color: #{{base08-hex}};
$destructive_fg_color: #{{base00-hex}};
$destructive_color: #{{base08-hex}};
$success_bg_color: #{{base0B-hex}};
$success_fg_color: #{{base00-hex}};
$success_color: #{{base0B-hex}};
$warning_bg_color: #{{base0A-hex}};
$warning_fg_color: #{{base00-hex}};
$warning_color: #{{base0A-hex}};
$error_bg_color: #{{base08-hex}};
$error_fg_color: #{{base00-hex}};
$error_color: #{{base08-hex}};
$selected_bg_color: #{{base0D-hex}};
$selected_fg_color: #{{base00-hex}};
$link_color: #{{base0D-hex}};
$link_visited_color: transparentize($link_color, 0.4);
$background_mix_factor: 0%;
$border_opacity: 1;
$shadow_color: transparent;
$text_shadow_color: transparent;
$focus_color: $selected_bg_color;
$focus_border_color: transparentize(#{{base05-hex}}, 0.5);
// _colors.scss
$base_color: #{{base01-hex}};
$bg_color: #{{base00-hex}};
$fg_color: #{{base05-hex}};
$osd_fg_color: #{{base05-hex}};
$osd_bg_color: #{{base01-hex}};
$system_base_color: #{{base00-hex}};
$system_fg_color: #{{base05-hex}};
$panel_bg_color: #{{base01-hex}};
$panel_fg_color: #{{base05-hex}};
$card_bg_color: #{{base01-hex}};
$card_shadow_color: transparent;
$card_shadow_border_color: transparent;
$borders_color: transparentize(#{{base05-hex}}, 0.8);
$outer_borders_color: transparentize(#{{base05-hex}}, 0.9);
$osd_borders_color: $borders_color;
$osd_outer_borders_color: $outer_borders_color;
$system_bg_color: #{{base00-hex}};
$system_borders_color: $borders_color;
$system_insensitive_fg_color: #{{base05-hex}};
$system_overlay_bg_color: #{{base01-hex}};
$insensitive_fg_color: #{{base04-hex}};
$insensitive_bg_color: #{{base00-hex}};
$insensitive_borders_color: $borders_color;
$checked_bg_color: #{{base01-hex}};
$checked_fg_color: #{{base05-hex}};
$hover_bg_color: #{{base01-hex}};
$hover_fg_color: #{{base05-hex}};
$active_bg_color: #{{base01-hex}};
$active_fg_color: #{{base05-hex}};
$accent_borders_color: transparentize(#{{base0D-hex}}, 0.5);
// Other required variables
$_base_color_light: #eeeeee;
$light_1: #ffffff;
$red_4: #{{base08-hex}};
$orange_4: #{{base09-hex}};

68
modules/gnome/hm.nix Normal file
View File

@ -0,0 +1,68 @@
{
pkgs,
config,
lib,
...
}: let
inherit (config.stylix.fonts) sansSerif serif monospace;
fontSize = toString config.stylix.fonts.sizes.applications;
documentFontSize = toString (config.stylix.fonts.sizes.applications - 1);
in {
options.stylix.targets.gnome.enable =
config.lib.stylix.mkEnableTarget "GNOME" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.gnome.enable) {
dconf.settings = {
"org/gnome/desktop/background" = {
color-shading-type = "solid";
picture-options = let
inherit (config.stylix) imageScalingMode;
in
if imageScalingMode == "fit"
then "scaled"
else if imageScalingMode == "fill"
then "zoom"
else if imageScalingMode == "stretch"
then "stretched"
else if imageScalingMode == "center"
then "centered"
# Seemingly no tile support... :(
else "zoom";
picture-uri = "file://${config.stylix.image}";
picture-uri-dark = "file://${config.stylix.image}";
};
"org/gnome/desktop/interface" = {
# We show the same colours regardless of this setting, and the quick
# settings tile is removed. The value is still used by Epiphany to
# request dark mode for websites which support it.
color-scheme =
if config.stylix.polarity == "dark"
then "prefer-dark"
else "default";
# Some GTK apps will use these font settings if they exist.
# i.e emacs-pgtk.
font-name = "${sansSerif.name} ${fontSize}";
document-font-name = "${serif.name} ${documentFontSize}";
monospace-font-name = "${monospace.name} ${fontSize}";
};
"org/gnome/shell/extensions/user-theme".name = "Stylix";
};
xdg.dataFile."themes/Stylix/gnome-shell/gnome-shell.css" = {
source = let
theme = pkgs.callPackage ./theme.nix {
inherit (config.lib.stylix) colors templates;
};
in "${theme}/share/gnome-shell/gnome-shell.css";
onChange = ''
if [[ -x "$(command -v gnome-extensions)" ]]; then
gnome-extensions disable user-theme@gnome-shell-extensions.gcampax.github.com
gnome-extensions enable user-theme@gnome-shell-extensions.gcampax.github.com
fi
'';
};
};
}

51
modules/gnome/nixos.nix Normal file
View File

@ -0,0 +1,51 @@
{ lib, pkgs, config, ... }:
let
theme = pkgs.callPackage ./theme.nix {
inherit (config.lib.stylix) colors templates;
};
in {
options.stylix.targets.gnome.enable =
config.lib.stylix.mkEnableTarget "GNOME and GDM" true;
config = lib.mkIf (
config.stylix.enable
&& config.stylix.targets.gnome.enable
&& (config.services.xserver.desktopManager.gnome.enable ||
config.services.xserver.displayManager.gdm.enable)
) {
# As Stylix is controlling the wallpaper, there is no need for this
# pack of default wallpapers to be installed.
# If you want to use one, you can set stylix.image to something like
# "${pkgs.gnome-backgrounds}/path/to/your/preferred/background"
# which will then download the pack regardless of its exclusion below.
environment.gnome.excludePackages = [ pkgs.gnome-backgrounds ];
nixpkgs.overlays = [(self: super: {
gnome-shell = super.gnome-shell.overrideAttrs (oldAttrs: {
# Themes are usually applied via an extension, but extensions are
# not available on the login screen. The only way to change the
# theme there is by replacing the default.
postFixup = (oldAttrs.postFixup or "") + ''
cp ${theme}/share/gnome-shell/gnome-shell-theme.gresource \
$out/share/gnome-shell/gnome-shell-theme.gresource
'';
patches = (oldAttrs.patches or []) ++ [
./shell_remove_dark_mode.patch
];
});
})];
# Cursor settings are usually applied via Home Manager,
# but the login screen uses a separate database.
environment.systemPackages = [ config.stylix.cursor.package ];
programs.dconf.profiles.gdm.databases = [{
lockAll = true;
settings."org/gnome/desktop/interface" = {
cursor-theme = config.stylix.cursor.name;
cursor-size = lib.gvariant.mkInt32 config.stylix.cursor.size;
};
}];
};
}

View File

@ -0,0 +1,40 @@
diff --git a/data/gnome-shell-theme.gresource.xml b/data/gnome-shell-theme.gresource.xml
index 8a4948e41..955ed5b13 100644
--- a/data/gnome-shell-theme.gresource.xml
+++ b/data/gnome-shell-theme.gresource.xml
@@ -11,7 +11,6 @@
<file>checkbox-off.svg</file>
<file>gnome-shell-dark.css</file>
<file>gnome-shell-light.css</file>
- <file>gnome-shell-high-contrast.css</file>
<file>gnome-shell-start.svg</file>
<file>pad-osd.css</file>
<file>process-working.svg</file>
diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
index 5b117ea71..67e7ce756 100644
--- a/data/theme/gnome-shell-sass/_common.scss
+++ b/data/theme/gnome-shell-sass/_common.scss
@@ -168,9 +168,9 @@ stage {
// tooltip
%tooltip {
- background-color: transparentize(black, 0.1);
- border: 1px solid transparentize($light_1, 0.9);
- color: $light_1;
+ background-color: transparentize($bg_color, 0.1);
+ border: 1px solid transparentize($base_color, 0.9);
+ color: $fg_color;
border-radius: 99px;
padding: $base_padding $base_padding * 2;
diff --git a/data/theme/gnome-shell-sass/widgets/_calendar.scss b/data/theme/gnome-shell-sass/widgets/_calendar.scss
index fc054da38..8e31741c1 100644
--- a/data/theme/gnome-shell-sass/widgets/_calendar.scss
+++ b/data/theme/gnome-shell-sass/widgets/_calendar.scss
@@ -27,6 +27,8 @@
.date-label {
@extend %title_2;
}
+
+ color: $fg_color !important;
}

View File

@ -0,0 +1,36 @@
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 9f4313b54..9deebbcf9 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -30,7 +30,6 @@ import * as BrightnessStatus from './status/brightness.js';
import * as SystemStatus from './status/system.js';
import * as LocationStatus from './status/location.js';
import * as NightLightStatus from './status/nightLight.js';
-import * as DarkModeStatus from './status/darkMode.js';
import * as BacklightStatus from './status/backlight.js';
import * as ThunderboltStatus from './status/thunderbolt.js';
import * as AutoRotateStatus from './status/autoRotate.js';
@@ -546,7 +545,6 @@ class QuickSettings extends PanelMenu.Button {
this._location = new LocationStatus.Indicator();
this._thunderbolt = new ThunderboltStatus.Indicator();
this._nightLight = new NightLightStatus.Indicator();
- this._darkMode = new DarkModeStatus.Indicator();
this._backlight = new BacklightStatus.Indicator();
this._powerProfiles = new PowerProfileStatus.Indicator();
this._rfkill = new RFKillStatus.Indicator();
@@ -567,7 +565,6 @@ class QuickSettings extends PanelMenu.Button {
this._indicators.add_child(this._nightLight);
if (this._network)
this._indicators.add_child(this._network);
- this._indicators.add_child(this._darkMode);
this._indicators.add_child(this._backlight);
this._indicators.add_child(this._powerProfiles);
if (this._bluetooth)
@@ -599,7 +596,6 @@ class QuickSettings extends PanelMenu.Button {
this._addItemsBefore(this._bluetooth.quickSettingsItems, sibling);
this._addItemsBefore(this._powerProfiles.quickSettingsItems, sibling);
this._addItemsBefore(this._nightLight.quickSettingsItems, sibling);
- this._addItemsBefore(this._darkMode.quickSettingsItems, sibling);
this._addItemsBefore(this._backlight.quickSettingsItems, sibling);
this._addItemsBefore(this._rfkill.quickSettingsItems, sibling);
this._addItemsBefore(this._autoRotate.quickSettingsItems, sibling);

View File

@ -0,0 +1,7 @@
{
services.xserver = {
enable = true;
desktopManager.gnome.enable = true;
displayManager.gdm.enable = true;
};
}

33
modules/gnome/theme.nix Normal file
View File

@ -0,0 +1,33 @@
{ stdenv, sass, glib, colors, templates }:
let
colorsScss = colors {
template = ./colors.mustache;
extension = "scss";
};
in stdenv.mkDerivation {
name = "${colors.slug}-gnome-shell-theme";
src = templates.gnome-shell;
patches = [ ./shell_colors.patch ];
postPatch = ''
rm data/theme/gnome-shell-sass/{_colors.scss,_default-colors.scss,_palette.scss}
cp ${colorsScss} data/theme/gnome-shell-sass/_colors.scss
'';
nativeBuildInputs = [ sass glib.dev ];
buildPhase = ''
sass data/theme/gnome-shell-light.scss \
>data/theme/gnome-shell-light.css
cp data/theme/gnome-shell-{light,dark}.css
glib-compile-resources \
--sourcedir=data/theme \
data/gnome-shell-theme.gresource.xml
'';
installPhase = ''
mkdir -p $out/share/gnome-shell
mv data/theme/gnome-shell-light.css $out/share/gnome-shell/gnome-shell.css
mv data/gnome-shell-theme.gresource $out/share/gnome-shell/gnome-shell-theme.gresource
'';
}

123
modules/grub/nixos.nix Normal file
View File

@ -0,0 +1,123 @@
{ pkgs, config, lib, ... }:
with config.lib.stylix;
with config.stylix.fonts;
with config.lib.stylix.colors.withHashtag;
let
# Grub requires fonts to be converted to "PFF2 format"
# This function takes a font { name, package } and produces a .pf2 file
mkGrubFont = font:
pkgs.runCommand "${font.package.name}.pf2" {
FONTCONFIG_FILE =
pkgs.makeFontsConf { fontDirectories = [ font.package ]; };
} ''
# Use fontconfig to select the correct .ttf or .otf file based on name
font=$(
${lib.getExe' pkgs.fontconfig "fc-match"} \
${lib.escapeShellArg font.name} \
--format=%{file}
)
# Convert to .pf2
${pkgs.grub2}/bin/grub-mkfont $font --output $out --size ${toString sizes.applications}
'';
inherit (config.stylix) imageScalingMode;
image-scale =
if imageScalingMode == "fill"
then "crop"
else if imageScalingMode == "fit"
then "fitheight"
else if imageScalingMode == "center"
then "padding"
# Grub doesn't seem to support tile
else "crop";
in {
options.stylix.targets.grub = {
enable = config.lib.stylix.mkEnableTarget "GRUB" true;
useImage = lib.mkOption {
description = "Whether to use your wallpaper image as the GRUB background.";
type = lib.types.bool;
default = false;
};
};
config.boot.loader.grub = lib.mkIf (config.stylix.enable && config.stylix.targets.grub.enable) {
backgroundColor = base00;
# Need to override the NixOS splash, this will match the background
splashImage = pixel "base00";
# This font will be used for the GRUB terminal
font = toString (mkGrubFont monospace);
# TODO: Include OS icons
theme = pkgs.runCommand "stylix-grub" {
themeTxt = ''
desktop-image: "background.png"
desktop-image-scale-method: "${image-scale}"
desktop-color: "${base00}"
title-text: ""
terminal-left: "10%"
terminal-top: "20%"
terminal-width: "80%"
terminal-height: "60%"
+ progress_bar {
left = 25%
top = 80%+20 # 20 pixels below boot menu
width = 50%
height = 30
id = "__timeout__"
show_text = true
font = "${sansSerif.name}"
text = "@TIMEOUT_NOTIFICATION_MIDDLE@"
border_color = "${base00}"
bg_color = "${base00}"
fg_color = "${base0B}"
text_color = "${base05}"
}
+ boot_menu {
left = 25%
top = 20%
width = 50%
height = 60%
menu_pixmap_style = "background_*.png"
item_height = 40
item_icon_space = 8
item_spacing = 0
item_padding = 0
item_font = "${sansSerif.name}"
item_color = "${base05}"
selected_item_color = "${base01}"
selected_item_pixmap_style = "selection_*.png"
}
'';
passAsFile = [ "themeTxt" ];
} ''
mkdir $out
cp $themeTxtPath $out/theme.txt
${if config.stylix.targets.grub.useImage
# Make sure the background image is .png by asking to convert it
then
"${pkgs.imagemagick}/bin/convert ${config.stylix.image} png32:$out/background.png"
else
"cp ${pixel "base00"} $out/background.png"}
cp ${pixel "base01"} $out/background_c.png
cp ${pixel "base0B"} $out/selection_c.png
cp ${mkGrubFont sansSerif} $out/sans_serif.pf2
'';
};
}

88
modules/gtk/gtk.mustache Normal file
View File

@ -0,0 +1,88 @@
@define-color accent_color #{{base0D-hex}};
@define-color accent_bg_color #{{base0D-hex}};
@define-color accent_fg_color #{{base00-hex}};
@define-color destructive_color #{{base08-hex}};
@define-color destructive_bg_color #{{base08-hex}};
@define-color destructive_fg_color #{{base00-hex}};
@define-color success_color #{{base0B-hex}};
@define-color success_bg_color #{{base0B-hex}};
@define-color success_fg_color #{{base00-hex}};
@define-color warning_color #{{base0E-hex}};
@define-color warning_bg_color #{{base0E-hex}};
@define-color warning_fg_color #{{base00-hex}};
@define-color error_color #{{base08-hex}};
@define-color error_bg_color #{{base08-hex}};
@define-color error_fg_color #{{base00-hex}};
@define-color window_bg_color #{{base00-hex}};
@define-color window_fg_color #{{base05-hex}};
@define-color view_bg_color #{{base00-hex}};
@define-color view_fg_color #{{base05-hex}};
@define-color headerbar_bg_color #{{base01-hex}};
@define-color headerbar_fg_color #{{base05-hex}};
@define-color headerbar_border_color rgba({{base01-dec-r}}, {{base01-dec-g}}, {{base01-dec-b}}, 0.7);
@define-color headerbar_backdrop_color @window_bg_color;
@define-color headerbar_shade_color rgba(0, 0, 0, 0.07);
@define-color headerbar_darker_shade_color rgba(0, 0, 0, 0.07);
@define-color sidebar_bg_color #{{base01-hex}};
@define-color sidebar_fg_color #{{base05-hex}};
@define-color sidebar_backdrop_color @window_bg_color;
@define-color sidebar_shade_color rgba(0, 0, 0, 0.07);
@define-color secondary_sidebar_bg_color @sidebar_bg_color;
@define-color secondary_sidebar_fg_color @sidebar_fg_color;
@define-color secondary_sidebar_backdrop_color @sidebar_backdrop_color;
@define-color secondary_sidebar_shade_color @sidebar_shade_color;
@define-color card_bg_color #{{base01-hex}};
@define-color card_fg_color #{{base05-hex}};
@define-color card_shade_color rgba(0, 0, 0, 0.07);
@define-color dialog_bg_color #{{base01-hex}};
@define-color dialog_fg_color #{{base05-hex}};
@define-color popover_bg_color #{{base01-hex}};
@define-color popover_fg_color #{{base05-hex}};
@define-color popover_shade_color rgba(0, 0, 0, 0.07);
@define-color shade_color rgba(0, 0, 0, 0.07);
@define-color scrollbar_outline_color #{{base02-hex}};
@define-color blue_1 #{{base0D-hex}};
@define-color blue_2 #{{base0D-hex}};
@define-color blue_3 #{{base0D-hex}};
@define-color blue_4 #{{base0D-hex}};
@define-color blue_5 #{{base0D-hex}};
@define-color green_1 #{{base0B-hex}};
@define-color green_2 #{{base0B-hex}};
@define-color green_3 #{{base0B-hex}};
@define-color green_4 #{{base0B-hex}};
@define-color green_5 #{{base0B-hex}};
@define-color yellow_1 #{{base0A-hex}};
@define-color yellow_2 #{{base0A-hex}};
@define-color yellow_3 #{{base0A-hex}};
@define-color yellow_4 #{{base0A-hex}};
@define-color yellow_5 #{{base0A-hex}};
@define-color orange_1 #{{base09-hex}};
@define-color orange_2 #{{base09-hex}};
@define-color orange_3 #{{base09-hex}};
@define-color orange_4 #{{base09-hex}};
@define-color orange_5 #{{base09-hex}};
@define-color red_1 #{{base08-hex}};
@define-color red_2 #{{base08-hex}};
@define-color red_3 #{{base08-hex}};
@define-color red_4 #{{base08-hex}};
@define-color red_5 #{{base08-hex}};
@define-color purple_1 #{{base0E-hex}};
@define-color purple_2 #{{base0E-hex}};
@define-color purple_3 #{{base0E-hex}};
@define-color purple_4 #{{base0E-hex}};
@define-color purple_5 #{{base0E-hex}};
@define-color brown_1 #{{base0F-hex}};
@define-color brown_2 #{{base0F-hex}};
@define-color brown_3 #{{base0F-hex}};
@define-color brown_4 #{{base0F-hex}};
@define-color brown_5 #{{base0F-hex}};
@define-color light_1 #{{base01-hex}};
@define-color light_2 #{{base01-hex}};
@define-color light_3 #{{base01-hex}};
@define-color light_4 #{{base01-hex}};
@define-color light_5 #{{base01-hex}};
@define-color dark_1 #{{base01-hex}};
@define-color dark_2 #{{base01-hex}};
@define-color dark_3 #{{base01-hex}};
@define-color dark_4 #{{base01-hex}};
@define-color dark_5 #{{base01-hex}};

53
modules/gtk/hm.nix Normal file
View File

@ -0,0 +1,53 @@
{ pkgs, config, lib, ... }:
let
cfg = config.stylix.targets.gtk;
baseCss = config.lib.stylix.colors {
template = ./gtk.mustache;
extension = "css";
};
finalCss = pkgs.runCommandLocal "gtk.css" {} ''
cat ${baseCss} >>$out
echo ${lib.escapeShellArg cfg.extraCss} >>$out
'';
in {
options.stylix.targets.gtk = {
enable = config.lib.stylix.mkEnableTarget
"all GTK3, GTK4 and Libadwaita apps" true;
extraCss = lib.mkOption {
description = ''
Extra code added to `gtk-3.0/gtk.css` and `gtk-4.0/gtk.css`.
'';
type = lib.types.lines;
default = "";
example = ''
// Remove rounded corners
window.background { border-radius: 0; }
'';
};
};
config = lib.mkIf cfg.enable {
# programs.dconf.enable = true; required in system config
gtk = {
enable = true;
font = {
inherit (config.stylix.fonts.sansSerif) package name;
size = config.stylix.fonts.sizes.applications;
};
theme = {
package = pkgs.adw-gtk3;
name = "adw-gtk3";
};
};
xdg.configFile = {
"gtk-3.0/gtk.css".source = finalCss;
"gtk-4.0/gtk.css".source = finalCss;
};
};
}

11
modules/gtk/nixos.nix Normal file
View File

@ -0,0 +1,11 @@
{ config, lib, ... }:
{
options.stylix.targets.gtk.enable =
config.lib.stylix.mkEnableTarget "all GTK3, GTK4 and Libadwaita apps" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.gtk.enable) {
# Required for Home Manager's GTK settings to work
programs.dconf.enable = true;
};
}

27
modules/helix/hm.nix Normal file
View File

@ -0,0 +1,27 @@
{ pkgs, config, lib, ... }:
let
theme = config.lib.stylix.colors {
templateRepo = config.lib.stylix.templates.base16-helix;
};
# Removing the background exposes transparency from the terminal. The
# background might be helpful if the terminal isn't themed, so we only
# do this if transparency is actually enabled.
transparentTheme = pkgs.runCommandLocal "helix-transparent.toml" {} ''
sed 's/,\? bg = "base00"//g' <${theme} >$out
'';
in {
options.stylix.targets.helix.enable =
config.lib.stylix.mkEnableTarget "Helix" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.helix.enable && config.programs.helix.enable) {
programs.helix.settings.theme = "stylix";
xdg.configFile."helix/themes/stylix.toml".source =
if config.stylix.opacity.terminal == 1.0
then theme
else transparentTheme;
};
}

55
modules/hyprland/hm.nix Normal file
View File

@ -0,0 +1,55 @@
{ config, lib, ... }:
{
options.stylix.targets.hyprland = {
enable = config.lib.stylix.mkEnableTarget "Hyprland" true;
hyprpaper.enable = config.lib.stylix.mkEnableTarget "Hyprpaper" true;
};
config = let
cfg = config.stylix.targets.hyprland;
in
lib.mkIf
(
config.stylix.enable
&& cfg.enable
&& config.wayland.windowManager.hyprland.enable
)
(
lib.mkMerge [
{
wayland.windowManager.hyprland.settings = let
inherit (config.lib.stylix) colors;
rgb = color: "rgb(${color})";
rgba = color: alpha: "rgba(${color}${alpha})";
in {
decoration.shadow.color = rgba colors.base00 "99";
general = {
"col.active_border" = rgb colors.base0D;
"col.inactive_border" = rgb colors.base03;
};
group = {
"col.border_inactive" = rgb colors.base03;
"col.border_active" = rgb colors.base0D;
"col.border_locked_active" = rgb colors.base0C;
groupbar = {
text_color = rgb colors.base05;
"col.active" = rgb colors.base0D;
"col.inactive" = rgb colors.base03;
};
};
misc.background_color = rgb colors.base00;
};
}
(
lib.mkIf cfg.hyprpaper.enable {
services.hyprpaper.enable = true;
stylix.targets.hyprpaper.enable = true;
}
)
]
);
}

View File

@ -0,0 +1,15 @@
{ lib, pkgs, ... }:
{
environment.loginShellInit = lib.getExe pkgs.hyprland;
programs.hyprland.enable = true;
home-manager.sharedModules = [{
wayland.windowManager.hyprland = {
enable = true;
# We need something to open a window so that we can check the window borders
settings.bind = [ "ALT, RETURN, exec, ${lib.getExe pkgs.foot}" ];
};
}];
}

19
modules/hyprlock/hm.nix Normal file
View File

@ -0,0 +1,19 @@
{ config, lib, ... }:
with config.lib.stylix;
{
options.stylix.targets.hyprlock.enable = mkEnableTarget "Hyprlock" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.hyprlock.enable) {
programs.hyprlock.settings = {
background.path = "${config.stylix.image}";
input-field = with colors; {
outer_color = "rgb(${base03})";
inner_color = "rgb(${base00})";
font_color = "rgb(${base05})";
fail_color = "rgb(${base08})";
check_color = "rgb(${base0A})";
};
};
};
}

14
modules/hyprpaper/hm.nix Normal file
View File

@ -0,0 +1,14 @@
{ config, lib, ... }: {
options.stylix.targets.hyprpaper.enable =
config.lib.stylix.mkEnableTarget "Hyprpaper" true;
config =
lib.mkIf
(config.stylix.enable && config.stylix.targets.hyprpaper.enable)
{
services.hyprpaper.settings = {
preload = [ "${config.stylix.image}" ];
wallpaper = [ ",${config.stylix.image}" ];
};
};
}

98
modules/i3/hm.nix Normal file
View File

@ -0,0 +1,98 @@
{ config, lib, ... }:
with config.lib.stylix.colors.withHashtag;
let
text = base05;
urgent = base08;
focused = base0D;
unfocused = base03;
fonts = let
inherit (config.stylix) fonts;
in {
names = [ fonts.sansSerif.name ];
size = fonts.sizes.desktop * 1.0;
};
in {
options.stylix.targets.i3.enable =
config.lib.stylix.mkEnableTarget "i3" true;
config = lib.mkMerge [
(lib.mkIf config.stylix.targets.i3.enable {
xsession.windowManager.i3.config = {
inherit fonts;
colors = let
background = base00;
indicator = base0B;
in {
inherit background;
urgent = {
inherit background indicator text;
border = urgent;
childBorder = urgent;
};
focused = {
inherit background indicator text;
border = focused;
childBorder = focused;
};
focusedInactive = {
inherit background indicator text;
border = unfocused;
childBorder = unfocused;
};
unfocused = {
inherit background indicator text;
border = unfocused;
childBorder = unfocused;
};
placeholder = {
inherit background indicator text;
border = unfocused;
childBorder = unfocused;
};
};
# output."*".bg = "${config.stylix.image} fill";
};
})
{
# Merge this with your bar configuration using //config.lib.stylix.i3.bar
lib.stylix.i3.bar = {
inherit fonts;
colors = let
background = base00;
border = background;
in {
inherit background;
statusline = text;
separator = base03;
focusedWorkspace = {
inherit text background;
border = focused;
};
activeWorkspace = {
inherit border background;
text = focused;
};
inactiveWorkspace = {
inherit text border background;
};
urgentWorkspace = {
inherit text background;
border = urgent;
};
bindingMode = {
inherit text border;
background = urgent;
};
};
};
}
];
}

View File

@ -0,0 +1,22 @@
{ config, lib, ... }:
let
colors = config.lib.stylix.colors.withHashtag;
in
{
# Merge this with your bar's theme's overrides with //config.lib.stylix.i3status-rust.bar
config.lib.stylix.i3status-rust.bar = with colors; {
idle_bg = base00;
idle_fg = base05;
info_bg = base09;
info_fg = base00;
good_bg = base01;
good_fg = base05;
warning_bg = base0A;
warning_fg = base00;
critical_bg = base08;
critical_fg = base00;
separator_bg = base00;
separator_fg = base05;
};
}

126
modules/k9s/hm.nix Normal file
View File

@ -0,0 +1,126 @@
{ config, lib, ... }:
with config.lib.stylix.colors.withHashtag;
{
options.stylix.targets.k9s.enable =
config.lib.stylix.mkEnableTarget "k9s" true;
config = lib.mkIf config.stylix.targets.k9s.enable {
programs.k9s.skins.skin = {
k9s = {
body = {
fgColor = base05-hex;
bgColor = "default";
logoColor = base0C-hex;
};
prompt = {
fgColor = base05-hex;
bgColor = base00-hex;
suggestColor = base0A-hex;
};
info = {
fgColor = base0B-hex;
sectionColor = base05-hex;
};
dialog = {
fgColor = base05-hex;
bgColor = "default";
buttonFgColor = base05-hex;
buttonBgColor = base0C-hex;
buttonFocusFgColor = base0E-hex;
buttonFocusBgColor = base0B-hex;
labelFgColor = base0A-hex;
fieldFgColor = base05-hex;
};
frame = {
border = {
fgColor = base02-hex;
focusColor = base01-hex;
};
menu = {
fgColor = base05-hex;
keyColor = base0B-hex;
numKeyColor = base0B-hex;
};
crumbs = {
fgColor = base05-hex;
bgColor = base01-hex;
activeColor = base01-hex;
};
status = {
newColor = base08-hex;
modifyColor = base0C-hex;
addColor = base09-hex;
errorColor = base0D-hex;
highlightcolor = base0A-hex;
killColor = base03-hex;
completedColor = base03-hex;
};
title = {
fgColor = base05-hex;
bgColor = base01-hex;
highlightColor = base0A-hex;
counterColor = base0C-hex;
filterColor = base0B-hex;
};
};
views = {
charts = {
bgColor = "default";
defaultDialColors = [ base0C-hex base0D-hex ];
defaultChartColors = [ base0C-hex base0D-hex ];
};
table = {
fgColor = base05-hex;
bgColor = "default";
header = {
fgColor = base05-hex;
bgColor = "default";
sorterColor = base08-hex;
};
};
xray = {
fgColor = base05-hex;
bgColor = "default";
cursorColor = base01-hex;
graphicColor = base0C-hex;
showIcons = false;
};
yaml = {
keyColor = base0B-hex;
colonColor = base0C-hex;
valueColor = base05-hex;
};
logs = {
fgColor = base05-hex;
bgColor = "default";
indicator = {
fgColor = base05-hex;
bgColor = base0C-hex;
};
};
help = {
fgColor = base05-hex;
bgColor = base00-hex;
indicator.fgColor = base0D-hex;
};
};
};
};
};
}

271
modules/kde/hm.nix Normal file
View File

@ -0,0 +1,271 @@
{ pkgs, config, lib, ... }:
with config.stylix.fonts;
with config.lib.stylix.colors;
let
formatValue = value:
if builtins.isBool value
then if value then "true" else "false"
else builtins.toString value;
formatSection = path: data:
let
header = lib.concatStrings (map (p: "[${p}]") path);
formatChild = name: formatLines (path ++ [ name ]);
children = lib.mapAttrsToList formatChild data;
partitioned = lib.partition builtins.isString children;
directChildren = partitioned.right;
indirectChildren = partitioned.wrong;
in
lib.optional (directChildren != []) header ++
directChildren ++
lib.flatten indirectChildren;
formatLines = path: data:
if builtins.isAttrs data
then
if data?_immutable
then
if builtins.isAttrs data.value
then formatSection (path ++ [ "$i" ]) data.value
else "${lib.last path}[$i]=${formatValue data.value}"
else formatSection path data
else "${lib.last path}=${formatValue data}";
formatConfig = data:
lib.concatStringsSep "\n" (formatLines [] data);
# Marking a setting as immutable should prevent it being overwritten
# through the system settings menu.
makeImmutable = value: {
_immutable = true;
inherit value;
};
# PascalCase is the standard naming for color scheme files. Schemes named
# in kebab-case will load when selected manually, but don't work with a
# look and feel package.
colorschemeSlug = lib.concatStrings
(builtins.filter builtins.isString
(builtins.split "[^a-zA-Z]" scheme));
colorEffect = {
ColorEffect = 0;
ColorAmount = 0;
ContrastEffect = 1;
ContrastAmount = 0.5;
IntensityEffect = 0;
IntensityAmount = 0;
};
colors = {
BackgroundNormal = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}";
BackgroundAlternate = "${base01-rgb-r},${base01-rgb-g},${base01-rgb-b}";
DecorationFocus = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}";
DecorationHover = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}";
ForegroundNormal = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}";
ForegroundActive = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}";
ForegroundInactive = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}";
ForegroundLink = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}";
ForegroundVisited = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}";
ForegroundNegative = "${base08-rgb-r},${base08-rgb-g},${base08-rgb-b}";
ForegroundNeutral = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}";
ForegroundPositive = "${base0B-rgb-r},${base0B-rgb-g},${base0B-rgb-b}";
};
colorscheme = {
General = {
ColorScheme = colorschemeSlug;
Name = scheme;
};
"ColorEffects:Disabled" = colorEffect;
"ColorEffects:Inactive" = colorEffect;
"Colors:Window" = colors;
"Colors:View" = colors;
"Colors:Button" = colors;
"Colors:Tooltip" = colors;
"Colors:Complementary" = colors;
"Colors:Selection" = colors // {
BackgroundNormal = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}";
BackgroundAlternate = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}";
ForegroundNormal = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}";
ForegroundActive = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}";
ForegroundInactive = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}";
ForegroundLink = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}";
ForegroundVisited = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}";
};
WM = {
activeBlend = "${base0A-rgb-r},${base0A-rgb-g},${base0A-rgb-b}";
activeBackground = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}";
activeForeground = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}";
inactiveBlend = "${base03-rgb-r},${base03-rgb-g},${base03-rgb-b}";
inactiveBackground = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}";
inactiveForeground = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}";
};
};
wallpaperMetadata = {
KPlugin = {
Id = "stylix";
Name = "Stylix";
};
};
lookAndFeelMetadata = {
KPlugin = {
Id = "stylix";
Name = "Stylix";
Description = "Generated from your Home Manager configuration";
ServiceTypes = [ "Plasma/LookAndFeel" ];
Website = "https://github.com/danth/stylix";
};
};
lookAndFeelDefaults = {
kwinrc."org.kde.kdecoration2".library = "org.kde.breeze";
plasmarc.Theme.name = "default";
kdeglobals = {
KDE.widgetStyle = "Breeze";
General.ColorScheme = colorschemeSlug;
};
# This only takes effect on the first login.
Wallpaper.Image = "stylix";
};
# Contains a wallpaper package, a colorscheme file, and a look and feel
# package which depends on both.
themePackage = pkgs.runCommandLocal "stylix-kde-theme" {
colorscheme = formatConfig colorscheme;
wallpaperMetadata = builtins.toJSON wallpaperMetadata;
wallpaperImage = config.stylix.image;
lookAndFeelMetadata = builtins.toJSON lookAndFeelMetadata;
lookAndFeelDefaults = formatConfig lookAndFeelDefaults;
} ''
write_text() {
mkdir --parents "$(dirname "$2")"
printf '%s\n' "$1" >"$2"
}
PATH="${pkgs.imagemagick}/bin:$PATH"
wallpaper="$out/share/wallpapers/stylix"
look_and_feel="$out/share/plasma/look-and-feel/stylix"
mkdir --parents "$wallpaper/contents/images"
magick \
"$wallpaperImage" \
-thumbnail 400x250 \
"$wallpaper/contents/screenshot.png"
dimensions="$(identify -ping -format '%wx%h' "$wallpaperImage")"
magick "$wallpaperImage" "$wallpaper/contents/images/$dimensions.png"
write_text \
"$colorscheme" \
"$out/share/color-schemes/${colorschemeSlug}.colors"
write_text "$wallpaperMetadata" "$wallpaper/metadata.json"
write_text "$lookAndFeelMetadata" "$look_and_feel/metadata.json"
write_text "$lookAndFeelDefaults" "$look_and_feel/contents/defaults"
'';
# The cursor theme can be configured through a look and feel package,
# however its size cannot.
kcminputrc = {
Mouse = {
cursorSize = makeImmutable (toString config.stylix.cursor.size);
cursorTheme = makeImmutable config.stylix.cursor.name;
};
};
kded5rc = {
# The gtkconfig module copies settings from KDE to the GTK configuration.
# This blocks Home Manager activation because the same files are already
# managed by Stylix.
Module-gtkconfig = makeImmutable {
autoload = false;
};
};
kdeglobals = {
KDE.LookAndFeelPackage = makeImmutable "stylix";
General = rec {
font = makeImmutable "${sansSerif.name},${toString sizes.applications},-1,5,50,0,0,0,0,0";
fixed = makeImmutable "${monospace.name},${toString sizes.terminal},-1,5,50,0,0,0,0,0";
desktopFont = makeImmutable "${sansSerif.name},${toString sizes.desktop},-1,5,50,0,0,0,0,0";
menuFont = desktopFont;
taskbarFont = desktopFont;
toolBarFont = desktopFont;
smallestReadableFont = desktopFont;
};
};
configPackage = pkgs.runCommandLocal "stylix-kde-config" {
kcminputrc = formatConfig kcminputrc;
kded5rc = formatConfig kded5rc;
kdeglobals = formatConfig kdeglobals;
} ''
mkdir "$out"
printf '%s\n' "$kcminputrc" >"$out/kcminputrc"
printf '%s\n' "$kded5rc" >"$out/kded5rc"
printf '%s\n' "$kdeglobals" >"$out/kdeglobals"
'';
in {
options.stylix.targets.kde.enable =
config.lib.stylix.mkEnableTarget "KDE" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.kde.enable && pkgs.stdenv.hostPlatform.isLinux) {
home.packages = [ themePackage ];
xdg.systemDirs.config = [ "${configPackage}" ];
# plasma-apply-wallpaperimage is necessary to change the wallpaper
# after the first login.
#
# plasma-apply-lookandfeel is only here to trigger a hot reload, the theme
# would still be applied without it if you logged out and back in.
#
# Home Manager clears $PATH before running the activation script, but we
# want to avoid installing these tools explicitly because that would pull
# in large dependencies for people who aren't actually using KDE.
# The workaround used is to assume a list of common paths where the tools
# might be installed, and look there. The ideal solution would require
# changes to KDE to make it possible to update the wallpaper through
# config files alone.
home.activation.stylixLookAndFeel = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
global_path() {
for directory in /run/current-system/sw/bin /usr/bin /bin; do
if [[ -f "$directory/$1" ]]; then
printf '%s\n' "$directory/$1"
return 0
fi
done
return 1
}
if wallpaper_image="$(global_path plasma-apply-wallpaperimage)"; then
"$wallpaper_image" "${themePackage}/share/wallpapers/stylix"
else
verboseEcho \
"plasma-apply-wallpaperimage: command not found"
fi
if look_and_feel="$(global_path plasma-apply-lookandfeel)"; then
"$look_and_feel" --apply stylix
else
verboseEcho \
"Skipping plasma-apply-lookandfeel: command not found"
fi
'';
};
}

10
modules/kde/testbed.nix Normal file
View File

@ -0,0 +1,10 @@
{
services = {
displayManager.sddm.enable = true;
xserver = {
enable = true;
desktopManager.plasma5.enable = true;
};
};
}

35
modules/kitty/hm.nix Normal file
View File

@ -0,0 +1,35 @@
{ config, lib, ... }:
let
cfg = config.stylix.targets.kitty;
theme = config.lib.stylix.colors {
templateRepo = config.lib.stylix.templates.tinted-kitty;
target = if cfg.variant256Colors then "default-256" else "default";
};
in {
options.stylix.targets.kitty = {
enable = config.lib.stylix.mkEnableTarget "Kitty" true;
variant256Colors = lib.mkOption {
description = ''
Whether to use the [256-color variant](https://github.com/kdrag0n/base16-kitty#256-color-variants)
rather than the default combination of colors.
'';
type = lib.types.bool;
default = false;
};
};
config = lib.mkIf cfg.enable {
programs.kitty = {
font = {
inherit (config.stylix.fonts.monospace) package name;
size = config.stylix.fonts.sizes.terminal;
};
settings.background_opacity = with config.stylix.opacity; "${builtins.toString terminal}";
extraConfig = ''
include ${theme}
'';
};
};
}

41
modules/kmscon/nixos.nix Normal file
View File

@ -0,0 +1,41 @@
{ config, lib, ... }:
{
options.stylix.targets.kmscon.enable =
config.lib.stylix.mkEnableTarget "the kmscon virtual console" true;
config.services.kmscon = lib.mkIf (config.stylix.enable && config.stylix.targets.kmscon.enable) {
fonts = [config.stylix.fonts.monospace];
extraConfig =
let
formatBase = name:
let
getComponent = comp: config.lib.stylix.colors."${name}-rgb-${comp}";
in
"${getComponent "r"},${getComponent "g"},${getComponent "b"}";
in ''
font-size=${builtins.toString config.stylix.fonts.sizes.terminal}
palette=custom
palette-black=${formatBase "base00"}
palette-red=${formatBase "base08"}
palette-green=${formatBase "base0B"}
palette-yellow=${formatBase "base0A"}
palette-blue=${formatBase "base0D"}
palette-magenta=${formatBase "base0E"}
palette-cyan=${formatBase "base0C"}
palette-light-grey=${formatBase "base05"}
palette-dark-grey=${formatBase "base03"}
palette-light-red=${formatBase "base08"}
palette-light-green=${formatBase "base0B"}
palette-light-yellow=${formatBase "base0A"}
palette-light-blue=${formatBase "base0D"}
palette-light-magenta=${formatBase "base0E"}
palette-light-cyan=${formatBase "base0C"}
palette-white=${formatBase "base07"}
palette-background=${formatBase "base00"}
palette-foreground=${formatBase "base05"}
'';
};
}

72
modules/kubecolor/hm.nix Normal file
View File

@ -0,0 +1,72 @@
{ config, lib, ... }:
{
options.stylix.targets.kubecolor.enable = config.lib.stylix.mkEnableTarget "kubecolor" true;
config = lib.mkIf config.stylix.targets.kubecolor.enable {
programs.kubecolor.settings = {
preset = if config.stylix.polarity == "either" then "" else "${config.stylix.polarity}";
theme = {
base = {
info = "fg=${config.lib.stylix.colors.withHashtag.base05-hex}";
primary = "fg=${config.lib.stylix.colors.withHashtag.base0E-hex}";
secondary = "fg=${config.lib.stylix.colors.withHashtag.base0D-hex}";
success = "fg=${config.lib.stylix.colors.withHashtag.base0B-hex}:bold";
warning = "fg=${config.lib.stylix.colors.withHashtag.base0A-hex}:bold";
danger = "fg=${config.lib.stylix.colors.withHashtag.base08-hex}:bold";
muted = "fg=${config.lib.stylix.colors.withHashtag.base04-hex}";
key = "fg=${config.lib.stylix.colors.withHashtag.base07-hex}:bold";
};
default = "fg=${config.lib.stylix.colors.withHashtag.base05-hex}";
data = {
key = "fg=${config.lib.stylix.colors.withHashtag.base07-hex}:bold";
string = "fg=${config.lib.stylix.colors.withHashtag.base05-hex}";
true = "fg=${config.lib.stylix.colors.withHashtag.base0B-hex}:bold";
false = "fg=${config.lib.stylix.colors.withHashtag.base08-hex}:bold";
number = "fg=${config.lib.stylix.colors.withHashtag.base0E-hex}";
null = "fg=${config.lib.stylix.colors.withHashtag.base04-hex}";
quantity = "fg=${config.lib.stylix.colors.withHashtag.base0E-hex}";
duration = "fg=${config.lib.stylix.colors.withHashtag.base09-hex}";
durationfresh = "fg=${config.lib.stylix.colors.withHashtag.base0B-hex}";
ratio = {
zero = "fg=${config.lib.stylix.colors.withHashtag.base04-hex}";
equal = "fg=${config.lib.stylix.colors.withHashtag.base0B-hex}";
unequal = "fg=${config.lib.stylix.colors.withHashtag.base0A-hex}";
};
};
status = {
success = "fg=${config.lib.stylix.colors.withHashtag.base0B-hex}:bold";
warning = "fg=${config.lib.stylix.colors.withHashtag.base0A-hex}:bold";
error = "fg=${config.lib.stylix.colors.withHashtag.base08-hex}:bold";
};
table = {
header = "fg=${config.lib.stylix.colors.withHashtag.base05-hex}:bold";
columns = "fg=${config.lib.stylix.colors.withHashtag.base05-hex}";
};
stderr = {
default = "fg=${config.lib.stylix.colors.withHashtag.base05-hex}";
error = "fg=${config.lib.stylix.colors.withHashtag.base08-hex}:bold";
};
describe = {
key = "fg=${config.lib.stylix.colors.withHashtag.base07-hex}:bold";
};
apply = {
created = "fg=${config.lib.stylix.colors.withHashtag.base0B-hex}";
configured = "fg=${config.lib.stylix.colors.withHashtag.base0A-hex}";
unchanged = "fg=${config.lib.stylix.colors.withHashtag.base05-hex}";
dryrun = "fg=${config.lib.stylix.colors.withHashtag.base0D-hex}";
fallback = "fg=${config.lib.stylix.colors.withHashtag.base05-hex}";
};
explain = {
key = "fg=${config.lib.stylix.colors.withHashtag.base07-hex}:bold";
required = "fg=${config.lib.stylix.colors.withHashtag.base00-hex}:bold";
};
options = {
flag = "fg=${config.lib.stylix.colors.withHashtag.base07-hex}:bold";
};
version = {
key = "fg=${config.lib.stylix.colors.withHashtag.base07-hex}:bold";
};
};
};
};
}

26
modules/lazygit/hm.nix Normal file
View File

@ -0,0 +1,26 @@
{
config,
lib,
...
}: let
colors = config.lib.stylix.colors.withHashtag;
in {
options.stylix.targets.lazygit.enable = config.lib.stylix.mkEnableTarget "lazygit" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.lazygit.enable) {
programs.lazygit.settings.gui.theme = {
activeBorderColor = [
colors.base07
"bold"
];
inactiveBorderColor = [colors.base04];
searchingActiveBorderColor = [colors.base02 "bold"];
optionsTextColor = [colors.base06];
selectedLineBgColor = [colors.base03];
cherryPickedCommitBgColor = [colors.base02];
cherryPickedCommitFgColor = [colors.base03];
unstagedChangesColor = [colors.base08];
defaultFgColor = [colors.base05];
};
};
}

31
modules/librewolf/hm.nix Normal file
View File

@ -0,0 +1,31 @@
# This module is a copy of the Firefox module.
{ config, lib, ... }:
let
profileSettings = {
settings = {
"font.name.monospace.x-western" = config.stylix.fonts.monospace.name;
"font.name.sans-serif.x-western" = config.stylix.fonts.sansSerif.name;
"font.name.serif.x-western" = config.stylix.fonts.serif.name;
};
};
makeProfileSettingsPair = profileName:
lib.nameValuePair profileName profileSettings;
in {
options.stylix.targets.librewolf = {
enable =
config.lib.stylix.mkEnableTarget "Librewolf" true;
profileNames = lib.mkOption {
description = "The Librewolf profile names to apply styling on.";
type = lib.types.listOf lib.types.str;
default = [ ];
};
};
config = lib.mkIf (config.stylix.enable && config.stylix.targets.librewolf.enable) {
programs.librewolf.profiles = lib.listToAttrs
(map makeProfileSettingsPair config.stylix.targets.librewolf.profileNames);
};
}

View File

@ -0,0 +1,9 @@
{ config, lib, ... }:
{
options.stylix.targets.lightdm.enable =
config.lib.stylix.mkEnableTarget "LightDM" true;
config.services.xserver.displayManager.lightdm.background =
lib.mkIf (config.stylix.enable && config.stylix.targets.lightdm.enable) config.stylix.image;
}

33
modules/mako/hm.nix Normal file
View File

@ -0,0 +1,33 @@
{ config, lib, options, ... }:
with config.lib.stylix.colors.withHashtag;
with config.stylix.fonts;
let
makoOpacity = lib.toHexString (((builtins.ceil (config.stylix.opacity.popups * 100)) * 255) / 100);
in {
options.stylix.targets.mako.enable =
config.lib.stylix.mkEnableTarget "Mako" true;
# Referenced https://github.com/stacyharper/base16-mako
config = lib.optionalAttrs (options.services ? mako) (lib.mkIf (config.stylix.enable && config.stylix.targets.mako.enable) {
services.mako = {
backgroundColor = base00 + makoOpacity;
borderColor = base0D;
textColor = base05;
progressColor = "over ${base02}";
font = "${sansSerif.name} ${toString sizes.popups}";
# I wish the mako hm module was like the dunst one
extraConfig = ''
[urgency=low]
background-color=${base00}${makoOpacity}
border-color=${base0D}
text-color=${base0A}
[urgency=high]
background-color=${base00}${makoOpacity}
border-color=${base0D}
text-color=${base08}
'';
};
});
}

37
modules/mangohud/hm.nix Normal file
View File

@ -0,0 +1,37 @@
{ config, lib, ... }:
let
inherit (config.stylix) fonts opacity;
inherit (config.lib.stylix) colors;
in {
options.stylix.targets.mangohud.enable = config.lib.stylix.mkEnableTarget "mangohud" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.mangohud.enable) {
programs.mangohud.settings = with colors; {
font_size = fonts.sizes.applications;
font_size_text = fonts.sizes.applications;
background_alpha = opacity.popups;
alpha = opacity.applications;
text_color = base05;
text_outline_color = base00;
background_color = base00;
gpu_color = base0B;
cpu_color = base0D;
vram_color = base0C;
media_player_color = base05;
engine_color = base0E;
wine_color = base0E;
frametime_color = base0B;
battery_color = base04;
io_color = base0A;
gpu_load_color = "${base0B}, ${base0A}, ${base08}";
cpu_load_color = "${base0B}, ${base0A}, ${base08}";
fps_color = "${base0B}, ${base0A}, ${base08}";
# TODO: Use the point unit:
# https://github.com/danth/stylix/issues/251.
font_scale = 1.33333;
};
};
}

33
modules/ncspot/hm.nix Normal file
View File

@ -0,0 +1,33 @@
{ config, lib, ... }:
{
options.stylix.targets.ncspot.enable =
config.lib.stylix.mkEnableTarget "Ncspot" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.ncspot.enable) {
programs.ncspot.settings =
let
colors = config.lib.stylix.colors.withHashtag;
in {
theme = with colors; {
background = base00;
primary = base05;
secondary = base03;
title = base06;
playing = base05;
playing_selected = base06;
playing_bg = base02;
highlight = base05;
highlight_bg = base02;
error = base07;
error_bg = base0F;
statusbar = base00;
statusbar_progress = base04;
statusbar_bg = base04;
cmdline = base05;
cmdline_bg = base00;
search_match = base05;
};
};
};
}

63
modules/neovim/hm.nix Normal file
View File

@ -0,0 +1,63 @@
{ pkgs, config, lib, ... }:
{
options.stylix.targets.neovim = {
enable = config.lib.stylix.mkEnableTarget "Neovim" true;
plugin = lib.mkOption {
type = lib.types.enum [ "base16-nvim" "mini.base16" ];
default = "mini.base16";
description = "Plugin used for the colorscheme";
};
transparentBackground = {
main = lib.mkEnableOption "background transparency for the main Neovim window";
signColumn = lib.mkEnableOption "background transparency for the Neovim sign column";
};
};
config = lib.mkIf (config.stylix.enable && config.stylix.targets.neovim.enable) {
programs.neovim =
let
cfg = config.stylix.targets.neovim;
in
{
plugins = [
(lib.mkIf (cfg.plugin == "base16-nvim") {
plugin = pkgs.vimPlugins.base16-nvim;
type = "lua";
config = with config.lib.stylix.colors.withHashtag; ''
require('base16-colorscheme').setup({
base00 = '${base00}', base01 = '${base01}', base02 = '${base02}', base03 = '${base03}',
base04 = '${base04}', base05 = '${base05}', base06 = '${base06}', base07 = '${base07}',
base08 = '${base08}', base09 = '${base09}', base0A = '${base0A}', base0B = '${base0B}',
base0C = '${base0C}', base0D = '${base0D}', base0E = '${base0E}', base0F = '${base0F}'
})
'';
})
(lib.mkIf (cfg.plugin == "mini.base16") {
plugin = pkgs.vimPlugins.mini-nvim;
type = "lua";
config = with config.lib.stylix.colors.withHashtag; ''
require('mini.base16').setup({
palette = {
base00 = '${base00}', base01 = '${base01}', base02 = '${base02}', base03 = '${base03}',
base04 = '${base04}', base05 = '${base05}', base06 = '${base06}', base07 = '${base07}',
base08 = '${base08}', base09 = '${base09}', base0A = '${base0A}', base0B = '${base0B}',
base0C = '${base0C}', base0D = '${base0D}', base0E = '${base0E}', base0F = '${base0F}'
}
})
'';
})
];
extraLuaConfig = lib.mkMerge [
(lib.mkIf cfg.transparentBackground.main ''
vim.cmd.highlight({ "Normal", "guibg=NONE", "ctermbg=NONE" })
vim.cmd.highlight({ "NonText", "guibg=NONE", "ctermbg=NONE" })
'')
(lib.mkIf cfg.transparentBackground.signColumn ''
vim.cmd.highlight({ "SignColumn", "guibg=NONE", "ctermbg=NONE" })
'')
];
};
};
}

View File

@ -0,0 +1,25 @@
{ pkgs, config, lib, ... }:
with config.lib.stylix.colors;
{
options.stylix.targets.nixos-icons.enable =
config.lib.stylix.mkEnableTarget "the NixOS logo" true;
config.nixpkgs.overlays = lib.mkIf (config.stylix.enable && config.stylix.targets.nixos-icons.enable) [(self: super: {
nixos-icons = super.nixos-icons.overrideAttrs (oldAttrs: {
src = pkgs.applyPatches {
inherit (oldAttrs) src;
prePatch = ''
substituteInPlace logo/nix-snowflake-white.svg --replace-fail '#ffffff' '#${base05}'
# Insert attribution comment after the XML prolog
sed \
--in-place \
'2i<!-- The original NixOS logo from ${oldAttrs.src.url} is licensed under https://creativecommons.org/licenses/by/4.0 and has been modified to match the ${scheme} color scheme. -->' \
logo/nix-snowflake-white.svg
'';
};
});
})];
}

View File

@ -0,0 +1 @@
import ./nixvim.nix

1
modules/nixvim/hm.nix Normal file
View File

@ -0,0 +1 @@
import ./nixvim.nix

1
modules/nixvim/nixos.nix Normal file
View File

@ -0,0 +1 @@
import ./nixvim.nix

87
modules/nixvim/nixvim.nix Normal file
View File

@ -0,0 +1,87 @@
{
config,
lib,
options,
...
}: let
cfg = config.stylix.targets.nixvim;
in {
options.stylix.targets.nixvim = {
enable = config.lib.stylix.mkEnableTarget "nixvim" true;
plugin = lib.mkOption {
type = lib.types.enum [ "base16-nvim" "mini.base16" ];
default = "mini.base16";
description = "Plugin used for the colorscheme";
};
transparentBackground = {
main = lib.mkEnableOption "background transparency for the main NeoVim window";
signColumn = lib.mkEnableOption "background transparency for the NeoVim sign column";
};
};
imports = [
(
lib.mkRenamedOptionModuleWith {
from = [ "stylix" "targets" "nixvim" "transparent_bg" "main" ];
sinceRelease = 2411;
to = [ "stylix" "targets" "nixvim" "transparentBackground" "main" ];
}
)
(
lib.mkRenamedOptionModuleWith {
from = [ "stylix" "targets" "nixvim" "transparent_bg" "sign_column" ];
sinceRelease = 2411;
to = [
"stylix"
"targets"
"nixvim"
"transparentBackground"
"signColumn"
];
}
)
];
config = lib.mkIf (config.stylix.enable && cfg.enable && (config.programs ? nixvim)) (
lib.optionalAttrs (builtins.hasAttr "nixvim" options.programs) (lib.mkMerge [
(lib.mkIf (cfg.plugin == "base16-nvim") {
programs.nixvim.colorschemes.base16 = {
enable = true;
colorscheme = {
inherit (config.lib.stylix.colors.withHashtag)
base00 base01 base02 base03 base04 base05 base06 base07
base08 base09 base0A base0B base0C base0D base0E base0F;
};
};
})
(lib.mkIf (cfg.plugin == "mini.base16") {
programs.nixvim.plugins.mini = {
enable = true;
modules.base16.palette = {
inherit (config.lib.stylix.colors.withHashtag)
base00 base01 base02 base03 base04 base05 base06 base07
base08 base09 base0A base0B base0C base0D base0E base0F;
};
};
})
{
programs.nixvim = {
highlight = let
transparent = {
bg = "none";
ctermbg = "none";
};
in {
Normal = lib.mkIf cfg.transparentBackground.main transparent;
NonText = lib.mkIf cfg.transparentBackground.main transparent;
SignColumn = lib.mkIf cfg.transparentBackground.signColumn transparent;
};
};
}
])
);
}

48
modules/nushell/hm.nix Normal file
View File

@ -0,0 +1,48 @@
{ config, lib, ... }:
with config.lib.stylix.colors.withHashtag;
{
options.stylix.targets.nushell.enable =
config.lib.stylix.mkEnableTarget "Nushell" true;
# Adapted from https://www.nushell.sh/book/coloring_and_theming.html#theming
config.programs.nushell.extraConfig = lib.mkIf (config.stylix.enable && config.stylix.targets.nushell.enable) ''
$env.config.color_config = {
separator: "${base03}"
leading_trailing_space_bg: "${base04}"
header: "${base0B}"
date: "${base0E}"
filesize: "${base0D}"
row_index: "${base0C}"
bool: "${base08}"
int: "${base0B}"
duration: "${base08}"
range: "${base08}"
float: "${base08}"
string: "${base04}"
nothing: "${base08}"
binary: "${base08}"
cellpath: "${base08}"
hints: dark_gray
shape_garbage: { fg: "${base07}" bg: "${base08}" }
shape_bool: "${base0D}"
shape_int: { fg: "${base0E}" attr: b }
shape_float: { fg: "${base0E}" attr: b }
shape_range: { fg: "${base0A}" attr: b }
shape_internalcall: { fg: "${base0C}" attr: b }
shape_external: "${base0C}"
shape_externalarg: { fg: "${base0B}" attr: b }
shape_literal: "${base0D}"
shape_operator: "${base0A}"
shape_signature: { fg: "${base0B}" attr: b }
shape_string: "${base0B}"
shape_filepath: "${base0D}"
shape_globpattern: { fg: "${base0D}" attr: b }
shape_variable: "${base0E}"
shape_flag: { fg: "${base0D}" attr: b }
shape_custom: { attr: b }
}
'';
}

View File

@ -0,0 +1,82 @@
{ config, pkgs, lib, ... }:
let
cfg = config.stylix.targets.plymouth;
theme = pkgs.runCommand "stylix-plymouth" { } ''
themeDir="$out/share/plymouth/themes/stylix"
mkdir -p $themeDir
${pkgs.imagemagick}/bin/convert \
-background transparent \
-bordercolor transparent \
${
# A transparent border ensures the image is not clipped when rotated
lib.optionalString cfg.logoAnimated "-border 42%"
} \
${cfg.logo} \
$themeDir/logo.png
${
if cfg.logoAnimated
then "cp ${./theme.script} $themeDir/stylix.script"
else "cp ${./theme_still.script} $themeDir/stylix.script"
}
${
with config.lib.stylix.colors;
''
substituteInPlace $themeDir/stylix.script \
--replace-fail "%BASE00%" "${base00-dec-r}, ${base00-dec-g}, ${base00-dec-b}" \
--replace-fail "%BASE05%" "${base05-dec-r}, ${base05-dec-g}, ${base05-dec-b}"
''
}
echo "
[Plymouth Theme]
Name=Stylix
ModuleName=script
[script]
ImageDir=$themeDir
ScriptFile=$themeDir/stylix.script
" > $themeDir/stylix.plymouth
'';
in {
options.stylix.targets.plymouth = {
enable = config.lib.stylix.mkEnableTarget "the Plymouth boot screen" true;
logo = lib.mkOption {
description = "Logo to be used on the boot screen.";
type = with lib.types; either path package;
defaultText = lib.literalMD "NixOS logo";
default = "${pkgs.nixos-icons}/share/icons/hicolor/256x256/apps/nix-snowflake.png";
};
logoAnimated = lib.mkOption {
description = ''
Whether to apply a spinning animation to the logo.
Disabling this allows the use of logos which don't have rotational
symmetry.
'';
type = lib.types.bool;
default = true;
};
};
imports = [
(
lib.mkRemovedOptionModule
[ "stylix" "targets" "plymouth" "blackBackground" ]
"This was removed since it goes against the chosen color scheme. If you want this, consider disabling the target and configuring Plymouth by hand."
)
];
config.boot.plymouth = lib.mkIf cfg.enable {
theme = "stylix";
themePackages = [ theme ];
};
}

View File

@ -0,0 +1,109 @@
center_x = Window.GetWidth() / 2;
center_y = Window.GetHeight() / 2;
baseline_y = Window.GetHeight() * 0.9;
### BACKGROUND ###
Window.SetBackgroundTopColor(%BASE00%);
Window.SetBackgroundBottomColor(%BASE00%);
### LOGO ###
logo.image = Image("logo.png");
logo.sprite = Sprite(logo.image);
logo.sprite.SetPosition(
center_x - (logo.image.GetWidth() / 2),
center_y - (logo.image.GetHeight() / 2),
1
);
logo.spinner_active = 1;
logo.spinner_third = 0;
logo.spinner_index = 0;
logo.spinner_max_third = 32;
logo.spinner_max = logo.spinner_max_third * 3;
real_index = 0;
for (third = 0; third < 3; third++) {
for (index = 0; index < logo.spinner_max_third; index++) {
subthird = index / logo.spinner_max_third;
angle = (third + ((Math.Sin(Math.Pi * (subthird - 0.5)) / 2) + 0.5)) / 3;
logo.spinner_image[real_index] = logo.image.Rotate(2*Math.Pi * angle);
real_index++;
}
}
fun activate_spinner () {
logo.spinner_active = 1;
}
fun deactivate_spinner () {
logo.spinner_active = 0;
logo.sprite.SetImage(logo.image);
}
fun refresh_callback () {
if (logo.spinner_active) {
logo.spinner_index = (logo.spinner_index + 1) % (logo.spinner_max * 2);
logo.sprite.SetImage(logo.spinner_image[Math.Int(logo.spinner_index / 2)]);
}
}
Plymouth.SetRefreshFunction(refresh_callback);
### PASSWORD ###
prompt = null;
bullets = null;
bullet.image = Image.Text("•", %BASE05%);
fun password_callback (prompt_text, bullet_count) {
deactivate_spinner();
prompt.image = Image.Text("Enter password", %BASE05%);
prompt.sprite = Sprite(prompt.image);
prompt.sprite.SetPosition(
center_x - (prompt.image.GetWidth() / 2),
baseline_y - prompt.image.GetHeight(),
1
);
total_width = bullet_count * bullet.image.GetWidth();
start_x = center_x - (total_width / 2);
bullets = null;
for (i = 0; i < bullet_count; i++) {
bullets[i].sprite = Sprite(bullet.image);
bullets[i].sprite.SetPosition(
start_x + (i * bullet.image.GetWidth()),
baseline_y + bullet.image.GetHeight(),
1
);
}
}
Plymouth.SetDisplayPasswordFunction(password_callback);
### NORMAL ###
fun normal_callback() {
prompt = null;
bullets = null;
activate_spinner();
}
Plymouth.SetDisplayNormalFunction(normal_callback);
### QUIT ###
fun quit_callback() {
prompt = null;
bullets = null;
deactivate_spinner();
}
Plymouth.SetQuitFunction(quit_callback);

View File

@ -0,0 +1,71 @@
center_x = Window.GetWidth() / 2;
center_y = Window.GetHeight() / 2;
baseline_y = Window.GetHeight() * 0.9;
### BACKGROUND ###
Window.SetBackgroundTopColor(%BASE00%);
Window.SetBackgroundBottomColor(%BASE00%);
### LOGO ###
logo.image = Image("logo.png");
logo.sprite = Sprite(logo.image);
logo.sprite.SetPosition(
center_x - (logo.image.GetWidth() / 2),
center_y - (logo.image.GetHeight() / 2),
1
);
### PASSWORD ###
prompt = null;
bullets = null;
bullet.image = Image.Text("•", %BASE05%);
fun password_callback (prompt_text, bullet_count) {
prompt.image = Image.Text("Enter password", %BASE05%);
prompt.sprite = Sprite(prompt.image);
prompt.sprite.SetPosition(
center_x - (prompt.image.GetWidth() / 2),
baseline_y - prompt.image.GetHeight(),
1
);
total_width = bullet_count * bullet.image.GetWidth();
start_x = center_x - (total_width / 2);
bullets = null;
for (i = 0; i < bullet_count; i++) {
bullets[i].sprite = Sprite(bullet.image);
bullets[i].sprite.SetPosition(
start_x + (i * bullet.image.GetWidth()),
baseline_y + bullet.image.GetHeight(),
1
);
}
}
Plymouth.SetDisplayPasswordFunction(password_callback);
### NORMAL ###
fun normal_callback() {
prompt = null;
bullets = null;
}
Plymouth.SetDisplayNormalFunction(normal_callback);
### QUIT ###
fun quit_callback() {
prompt = null;
bullets = null;
}
Plymouth.SetQuitFunction(quit_callback);

284
modules/qutebrowser/hm.nix Normal file
View File

@ -0,0 +1,284 @@
{
config,
lib,
...
}:
with config.lib.stylix.colors.withHashtag;
with config.stylix.fonts; let
background = base00;
secondary-background = base01;
selection-background = base03;
foreground = base05;
inverted-foreground = base00;
error = base08;
info = base0B;
secondary-info = base0C;
warning = base0E;
in {
options.stylix.targets.qutebrowser.enable =
config.lib.stylix.mkEnableTarget "Qutebrowser" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.qutebrowser.enable) {
programs.qutebrowser.settings = {
colors = {
completion = {
category = {
bg = background;
fg = info;
border = {
bottom = background;
top = background;
};
};
even.bg = background;
fg = foreground;
item.selected = {
bg = selection-background;
border = {
bottom = selection-background;
top = selection-background;
};
fg = foreground;
};
match.fg = info;
odd.bg = secondary-background;
scrollbar = {
bg = background;
fg = foreground;
};
};
contextmenu = {
disabled = {
bg = secondary-background;
fg = inverted-foreground;
};
menu = {
bg = background;
fg = foreground;
};
selected = {
bg = selection-background;
fg = foreground;
};
};
downloads = {
bar.bg = background;
error = {
bg = error;
fg = inverted-foreground;
};
start = {
bg = info;
fg = inverted-foreground;
};
stop = {
bg = secondary-info;
fg = inverted-foreground;
};
};
hints = {
bg = secondary-background;
fg = foreground;
match.fg = info;
};
keyhint = {
bg = background;
fg = foreground;
suffix.fg = foreground;
};
messages = {
error = {
bg = error;
fg = inverted-foreground;
border = error;
};
info = {
bg = info;
fg = inverted-foreground;
border = info;
};
warning = {
bg = warning;
fg = inverted-foreground;
border = warning;
};
};
prompts = {
bg = background;
border = background;
fg = foreground;
selected.bg = secondary-background;
};
statusbar = {
caret = {
bg = selection-background;
fg = foreground;
selection = {
bg = selection-background;
fg = foreground;
};
};
command = {
bg = background;
fg = foreground;
private = {
bg = secondary-background;
fg = foreground;
};
};
insert = {
bg = info;
fg = inverted-foreground;
};
normal = {
bg = background;
fg = foreground;
};
passthrough = {
bg = secondary-info;
fg = inverted-foreground;
};
private = {
bg = secondary-background;
fg = foreground;
};
progress.bg = info;
url = {
error.fg = error;
fg = foreground;
hover.fg = foreground;
success = {
http.fg = secondary-info;
https.fg = info;
};
warn.fg = warning;
};
};
tabs = {
bar.bg = background;
even = {
bg = secondary-background;
fg = foreground;
};
indicator = {
inherit error;
start = secondary-info;
stop = info;
};
odd = {
bg = background;
fg = foreground;
};
pinned = {
even = {
bg = info;
fg = inverted-foreground;
};
odd = {
bg = secondary-info;
fg = inverted-foreground;
};
selected = {
even = {
bg = selection-background;
fg = foreground;
};
odd = {
bg = selection-background;
fg = foreground;
};
};
};
selected = {
even = {
bg = selection-background;
fg = foreground;
};
odd = {
bg = selection-background;
fg = foreground;
};
};
};
webpage = let
isDark = config.stylix.polarity == "dark";
in {
darkmode.enabled = lib.mkIf isDark (lib.mkDefault true);
preferred_color_scheme =
lib.mkIf
isDark (lib.mkDefault config.stylix.polarity);
};
};
fonts = {
default_family = sansSerif.name;
default_size = "${toString sizes.applications}pt";
web = {
family = {
cursive = serif.name;
fantasy = serif.name;
fixed = monospace.name;
sans_serif = sansSerif.name;
serif = serif.name;
standard = sansSerif.name;
};
# TODO: Use the pixel unit:
# https://github.com/danth/stylix/issues/251.
size.default = builtins.floor (sizes.applications * 4 / 3 + 0.5);
};
};
hints.border = background;
};
};
}

46
modules/regreet/nixos.nix Normal file
View File

@ -0,0 +1,46 @@
{
pkgs,
config,
lib,
...
}:
{
options.stylix.targets.regreet.enable = config.lib.stylix.mkEnableTarget "ReGreet" true;
config =
lib.mkIf
(config.stylix.enable && config.stylix.targets.regreet.enable && pkgs.stdenv.hostPlatform.isLinux)
{
programs.regreet = {
settings.background = {
path = config.stylix.image;
fit = let
inherit (config.stylix) imageScalingMode;
in
if imageScalingMode == "fill"
then "Cover"
else if imageScalingMode == "fit"
then "Contain"
else if imageScalingMode == "stretch"
then "Fill"
# No other available options
else null;
};
font = {
inherit (config.stylix.fonts.sansSerif) name package;
};
cursorTheme = {
inherit (config.stylix.cursor) name package;
};
theme = {
package = pkgs.adw-gtk3;
name = "adw-gtk3";
};
extraCss = config.lib.stylix.colors {
template = ./../gtk/gtk.mustache;
extension = "css";
};
};
};
}

14
modules/river/hm.nix Normal file
View File

@ -0,0 +1,14 @@
{ config, lib, ... }:
{
options.stylix.targets.river.enable = config.lib.stylix.mkEnableTarget "River" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.river.enable) {
wayland.windowManager.river.settings = {
border-color-focused = "0x${config.lib.stylix.colors.base0D}";
border-color-unfocused = "0x${config.lib.stylix.colors.base03}";
border-color-urgent = "0x${config.lib.stylix.colors.base08}";
xcursor-theme = config.stylix.cursor.name;
};
};
}

144
modules/rofi/hm.nix Normal file
View File

@ -0,0 +1,144 @@
{ config, lib, ... }:
with config.stylix.fonts;
let
inherit (config.lib.formats.rasi) mkLiteral;
mkRgba = opacity: color:
let
c = config.lib.stylix.colors;
r = c."${color}-rgb-r";
g = c."${color}-rgb-g";
b = c."${color}-rgb-b";
in
mkLiteral
"rgba ( ${r}, ${g}, ${b}, ${opacity} % )";
mkRgb = mkRgba "100";
rofiOpacity = builtins.toString (builtins.ceil (config.stylix.opacity.popups * 100));
in
{
options.stylix.targets.rofi.enable =
config.lib.stylix.mkEnableTarget "Rofi" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.rofi.enable) {
programs.rofi = {
font = "${monospace.name} ${toString sizes.popups}";
theme = {
"*" = {
background = mkRgba rofiOpacity "base00";
lightbg = mkRgba rofiOpacity "base01";
red = mkRgba rofiOpacity "base08";
blue = mkRgba rofiOpacity "base0D";
lightfg = mkRgba rofiOpacity "base06";
foreground = mkRgba rofiOpacity "base05";
background-color = mkRgb "base00";
separatorcolor = mkLiteral "@foreground";
border-color = mkLiteral "@foreground";
selected-normal-foreground = mkLiteral "@lightbg";
selected-normal-background = mkLiteral "@lightfg";
selected-active-foreground = mkLiteral "@background";
selected-active-background = mkLiteral "@blue";
selected-urgent-foreground = mkLiteral "@background";
selected-urgent-background = mkLiteral "@red";
normal-foreground = mkLiteral "@foreground";
normal-background = mkLiteral "@background";
active-foreground = mkLiteral "@blue";
active-background = mkLiteral "@background";
urgent-foreground = mkLiteral "@red";
urgent-background = mkLiteral "@background";
alternate-normal-foreground = mkLiteral "@foreground";
alternate-normal-background = mkLiteral "@lightbg";
alternate-active-foreground = mkLiteral "@blue";
alternate-active-background = mkLiteral "@lightbg";
alternate-urgent-foreground = mkLiteral "@red";
alternate-urgent-background = mkLiteral "@lightbg";
# Text Colors
base-text = mkRgb "base05";
selected-normal-text = mkRgb "base01";
selected-active-text = mkRgb "base00";
selected-urgent-text = mkRgb "base00";
normal-text = mkRgb "base05";
active-text = mkRgb "base0D";
urgent-text = mkRgb "base08";
alternate-normal-text = mkRgb "base05";
alternate-active-text = mkRgb "base0D";
alternate-urgent-text = mkRgb "base08";
};
window.background-color = mkLiteral "@background";
message.border-color = mkLiteral "@separatorcolor";
textbox.text-color = mkLiteral "@base-text";
listview.border-color = mkLiteral "@separatorcolor";
element-text = {
background-color = mkLiteral "inherit";
text-color = mkLiteral "inherit";
};
element-icon = {
background-color = mkLiteral "inherit";
text-color = mkLiteral "inherit";
};
"element normal.normal" = {
background-color = mkLiteral "@normal-background";
text-color = mkLiteral "@normal-text";
};
"element normal.urgent" = {
background-color = mkLiteral "@urgent-background";
text-color = mkLiteral "@urgent-text";
};
"element normal.active" = {
background-color = mkLiteral "@active-background";
text-color = mkLiteral "@active-text";
};
"element selected.normal" = {
background-color = mkLiteral "@selected-normal-background";
text-color = mkLiteral "@selected-normal-text";
};
"element selected.urgent" = {
background-color = mkLiteral "@selected-urgent-background";
text-color = mkLiteral "@selected-urgent-text";
};
"element selected.active" = {
background-color = mkLiteral "@selected-active-background";
text-color = mkLiteral "@selected-active-text";
};
"element alternate.normal" = {
background-color = mkLiteral "@alternate-normal-background";
text-color = mkLiteral "@alternate-normal-text";
};
"element alternate.urgent" = {
background-color = mkLiteral "@alternate-urgent-background";
text-color = mkLiteral "@alternate-urgent-text";
};
"element alternate.active" = {
background-color = mkLiteral "@alternate-active-background";
text-color = mkLiteral "@alternate-active-text";
};
scrollbar.handle-color = mkLiteral "@normal-foreground";
sidebar.border-color = mkLiteral "@separatorcolor";
button.text-color = mkLiteral "@normal-text";
"button selected" = {
background-color = mkLiteral "@selected-normal-background";
text-color = mkLiteral "@selected-normal-text";
};
inputbar.text-color = mkLiteral "@normal-text";
case-indicator.text-color = mkLiteral "@normal-text";
entry.text-color = mkLiteral "@normal-text";
prompt.text-color = mkLiteral "@normal-text";
textbox-prompt-colon.text-color = mkLiteral "inherit";
};
};
};
}

1
modules/spicetify/hm.nix Normal file
View File

@ -0,0 +1 @@
import ./spicetify.nix

View File

@ -0,0 +1 @@
import ./spicetify.nix

View File

@ -0,0 +1,45 @@
{ config, options, lib, pkgs, ... }:
{
options.stylix.targets.spicetify.enable =
config.lib.stylix.mkEnableTarget "Spicetify" true;
config = lib.mkIf (config.stylix.enable && config.stylix.targets.spicetify.enable && (config.programs?spicetify)) (
lib.optionalAttrs (builtins.hasAttr "spicetify" options.programs) {
programs.spicetify = {
theme = {
name = "stylix";
src = pkgs.writeTextFile {
name = "color.ini";
destination = "/color.ini";
text = with config.lib.stylix.colors; ''
[base]
text = ${base05}
subtext = ${base05}
main = ${base00}
main-elevated = ${base02}
highlight = ${base02}
highlight-elevated = ${base03}
sidebar = ${base01}
player = ${base05}
card = ${base04}
shadow = ${base00}
selected-row = ${base05}
button = ${base05}
button-active = ${base05}
button-disabled = ${base04}
tab-active = ${base02}
notification = ${base02}
notification-error = ${base08}
equalizer = ${base0B}
misc = ${base02}
'';
};
# Sidebar configuration is incompatible with the default navigation bar
sidebarConfig = false;
};
colorScheme = "base";
};
}
);
}

Some files were not shown because too many files have changed in this diff Show More