Niji
Niji is an extensible theming framework that brings uniform, responsive and comfortable theming to the tinkerer's desktop. It currently comes with builtin support for GTK apps, sway, hyprland, kitty, and others, but it also allows you to easily add custom modules for anything you desire.
Refer to Getting Started for a quick guide on how to set niji up, or take a look at Configuration and Built-in Modules for a more in-depth reference of niji's capabilities.
Getting Started
Installation
AUR
Arch Linux users can install niji from the AUR using the niji-git package.
Manually
To install niji manually from source, do the following steps:
- Clone the git repository and enter the folder
- Install using cargo:
cargo install --path ./crates/main - Create the config directory:
mkdir ~/.config/niji - Install the builtin modules:
cp ./assets/modules ~/.config/niji/modules - Install the builtin themes:
cp ./assets/themes ~/.config/niji/themes
Initial Configuration
Create the configuration file at ~/.config/niji/config.toml. The first step is
to choose which modules to use. Take a look at Built-in Modules
for a list of available modules. Simply set your desired modules using this
syntax:
modules = ["hyprland", "waybar"]
Afterwards, you should set font_family, cursor_theme and cursor_size as
basic preferences. Make sure you have the cursor theme installed that you
select.
modules = ["hyprland", "waybar"]
[global]
font_family = "Fira Sans"
cursor_theme = "Adwaita"
cursor_size = 22
Lastly, be sure to refer to the documentation of each of your selected modules and check for available configuration options and additional necessary steps for activation.
You can now list available themes using niji theme list, and preview them
using niji theme show <name>. If you've picked one, apply it using
niji theme set <name>.
Next Steps
After the initial setup, you may want to consider taking a look at Configuration for some advanced configuration options.
If you want to use a custom theme, refer to Custom Themes.
If you want to apply your theme to an application that isn't supported out of the box, you can take a look at Custom Modules.
Configuration
Niji is configured via its config file, which lies at
~/.config/niji/config.toml (Assuming you don't have a custom
$XDG_CONFIG_HOME set). The config file uses TOML syntax.
Base Configuration
The base configuration configures the behavior of the niji framework itself.
These options go at the top level of config.toml. Currently, the following
options are available:
# A list of module names to activate.
# This value is required.
modules = []
# A list of module names that shouldn't be automatically reloaded.
# This is useful if the reloading behavior of that module interferes with your
# specific configuration.
disable_reloads = []
Module Configuration
Configuration options for modules appear after a header containing their name.
The one exception is the special [global] header, which applies to all
modules.
All module configuration options are optional, but if you want consistency across different theming targets, it is a good idea to set the available global options that make sense for your setup, since default behaviors may differ from module to module.
Global Options
The available global module configuration options are as follows, shown here with example values:
[global]
# The font family to use for UI
font_family = "Fira Sans"
# A scaling factor for text.
# Use this if you want larger text for better visibility, or smaller text for
# a more compact UI.
font_scale = 1.0
# The cursor theme to use
cursor_theme = "Adwaita"
# The cursor size to use
cursor_size = 22
You can also override any of these options individually for each module, simply by adding to the corresponding section. For example, you could configure the waybar module to use a different font like this:
[waybar]
font_family = "Fira Code"
Setting Wallpapers per Theme
If you have a module that supports setting wallpapers, such as
hyprpaper, you can set a global wallpaper map, that
specifies which wallpaper to use for each theme. You can do this by adding a
[global.wallpaper] heading to your config, with keys corresponding to the
theme names, and values corresponding to the path to the wallpaper. You can also
add a default key as a fallback.
An example configuration might look like this:
[global.wallpaper]
default = "./wallpapers/wp1.png"
tokyonight = "./wallpapers/wp2.png"
dracula = "./wallpapers/wp3.png"
If you just want to use a single wallpaper for every theme, you can also just set the wallpaper option like this:
[global]
wallpaper = "./wallpaper/my-wallpaper.png"
Module-Specific Options
Module-specific options come after a header with the name of the corresponding
module. An example configuration for the waybar module
might look like this:
[waybar]
icon_font = "Material Design Icons"
show_shadow = false
module_margin = 8
What specific options are available differs from module to module. If you are using a builtin module, you can find their respective documentation in Built-In Modules.
Command Line Interface
To get help with the CLI you can always use niji help or
niji help <command>.
Usage: niji [OPTIONS]
Global Options
These options are available for all commands.
| Name | Description |
|---|---|
-q, --quiet | Disable log output |
-v, --verbose | Print debug messages |
-b, --no-color | Disable colored output |
-h, --help | Print help |
-V, --version | Print version number |
Commands
niji apply [OPTIONS]
Applies (or re-applies) the current theme and configuration to all active
modules, or to the selected modules if --module is used.
Options
| Name | Description |
|---|---|
-M, --module <modules> | Apply the specified modules rather than the active ones. Can be set multiple times. |
-k, --no-reload | Don't reload the affected modules |
niji theme get
Return the name of the currently active theme
niji theme show [name]
Print a preview of the theme with name [name], or the active theme if [name]
is omitted.
niji theme set [name]
Set the active theme to [name]. By default, this command also applies the
theme to all active modules (can be disabled using --no-apply), and reloads
them (can be disabled using --no-reload).
Options
| Name | Description |
|---|---|
-n, --no-apply | Don't apply the theme after setting it |
-k --no-reload | Don't reload the affected modules |
niji theme list
List the names of all installed themes
niji theme unset
Unsets the currently set theme. Does not apply or reload any modules.
Built-in Themes
Niji includes a number of built-in themes. You can preview them using the
niji theme show <name> command, and select them using niji theme set <name>.
For more information, refer to Command Line Interface.
The built-in themes currently included with niji are:
catpuccin-frappecatpuccin-lattedraculagruvboxgruvbox-lighttokyonight
To list these themes, along with any custom or separately installed themes, use
the niji theme list command.
If there is something missing from this list that you'd like to have, take a look at Custom Themes.
Built-in Modules
Niji includes a number of modules already built-in. You can simply activate them
by adding their names to the "modules" list in your config.toml. For more
details, see Configuration, and the documentation of the
respective module.
The built-in modules currently included with niji are:
gtk: Theming GTK3 and GTK4 applicationshyprland: Theming hyprland window decorationshyprpaper: Wallpaper setting support for hyprpaperkitty: Theming kitty window and terminal colorsmako: Theming mako notificationssway: Theming sway window decorations and setting swaybg wallpapersswaylock: Theming your swaylock lock screenwaybar: A fully managed waybar theme
If there is something missing from this list that you'd like to have, take a look at Custom Modules.
Module gtk
The gtk module allows you to theme GTK3 and GTK4 applications. Note that other
targets for GTK themes, such as GTK2, qt6gtk2, gnome-shell, etc. are currently
not supported.
The niji theme is a modified version of the amazing Colloid theme by vinceliuice.
Activating
To activate the module, add it to your config.toml:
modules = ["gtk"]
This will export a GTK theme called "niji" to your system. If you have reloads
enabled for this module (which they are by default), niji will also
automatically set the system GTK theme when applying. If you don't want this
behavior, you can disable it by adding "gtk" to your disable_reloads list
(see Configuration).
libadwaita
Apps that use libadwaita, such as nautilus, are quite stubborn when it comes to
convincing them to use a gtk theme other than Adwaita. The easiest way to fix
this is to globally set the environment variable GTK_THEME to niji, which
works.
If you are using Arch Linux, you can also use libadwaita-without-adwaita-git for an arguably cleaner solution; this patched version of libadwaita properly respects your system GTK theme, and makes apps like nautilus work properly with niji, nwg-look, and other tools, out of the box.
Configuration
The following global configuration options are relevant to this module:
cursor_themecursor_sizefont_familyfont_scale
See Configuration for a detailed explanation. Note that these options do not work if reloads are disabled for this module.
Additionally, these module-specific configuration options can be added to
config.toml (shown here with their default values):
[gtk]
# Set to true to use a more compact layout in GTK apps
compact = false
# Set to "normal" for less flashy window buttons
window_button = "mac"
Module hyprland
The hyprland module allows you to theme the window decoration of the
Hyprland wayland compositor.
The configuration produced by this module is intentionally minimal, and does not interfere with your existing hyprland config.
See also the hyprpaper module.
Activating
To activate the module, add it to your config.toml:
modules = ["hyprland"]
Niji will now output a hyprland configuration file to
~/.local/share/niji/hyprland/theme.conf. To enable it, add the following line
to the bottom of your hyprland.conf:
source = ~/.local/share/niji/hyprland/theme.conf
You can, of course, override as much of the generated configuration as you like, simply by adding configuration after the source statement.
Configuration
The following global configuration options are relevant to this module:
cursor_themecursor_size
See Configuration for a detailed explanation.
Additionally, these module-specific configuration options can be added to
config.toml (shown here with their default values):
[hyprland]
# Can be either "background", "surface", "primary" or "secondary".
# This value determines which theme color is used for focused window borders.
focused_color = "surface"
# Suppress the warning that is displayed when the generated config file hasn't been sourced
suppress_not_sourced_warning = false
Module hyprpaper
The hyprpaper module allows you to automatically reconfigure
hyprpaper to use a specific wallpaper for
each theme.
See also the hyprland module.
Activating
To activate the module, add it to your config.toml:
modules = ["hyprpaper"]
This will cause niji to take control of your .config/hypr/hyprpaper.conf file.
Configuration
In order for this module to do anything, you have to have a wallpaper map configured. See Setting Wallpapers per Theme for information on how to do that.
Beyond that, these module-specific configuration options can be added to
config.toml (shown here with their default values):
[hyprpaper]
# Set to true to show the hyprland splash text on the wallpaper
splash = false
# The command to be used to start hyprpaper when restarting it
hyprpaper_command = "hyprpaper > /dev/null"
Module kitty
The kitty module allows you to set the window and terminal colors for the
kitty terminal emulator.
Activating
Th activate the module, add it to your config.toml:
modules = ["kitty"]
This will create a kitty theme called "niji". If you have reloads enabled for
this module (which they are by default), niji will also automatically apply this
theme. If you do not want this behaviour, you can disable it by adding "kitty"
to your disable_reloads list (see
Configuration).
Configuration
These module-specific configuration options can be added to config.toml (shown
here with their default values):
[kitty]
# The opacity of the terminal background
background_opacity = 1.0
# The foreground color. Can be any key from the [terminal] section of the theme,
# or a custom color, such as "#ff0000".
foreground = "bright_white"
Module mako
The mako module allows you to theme notifications produced by the
mako notification daemon.
Activating
To activate the module, add it to your config.toml:
modules = ["mako"]
This will cause niji to take control of your .config/mako/config file.
Configuration
The following global configuration options are relevant to this module:
font_familyfont_scale
See Configuration for a detailed explanation.
Additionally, these module-specific configuration options can be added to
config.toml (shown here with their default values):
[mako]
# The border width around notifications
border_width = 2
# The border radius of notifications
border_radius = 10
# The background transparency of the popup
popup_alpha = 1.0
# Set to a path string to set more configuration options
custom_config_file = false
Since niji needs to take control of .config/mako/config, if you want to set
any of mako's numerous additional configuration options that have nothing to do
with theming, you'll have to create a separate configuration file in your
.config/niji directory, and link to it in config.toml. For example, if you
wanted to set the default timeout of notifications, you might do something like
this:
~/.config/niji/config.toml
# ...
[mako]
custom_config_file = "./custom/mako_config"
~/.config/niji/custom/mako_config
default-timeout=10000
Module sway
The sway module allows you to theme sway
window decorations, as well as setting your swaybg wallpaper per theme.
Activating
To activate the module, add it to your config.toml:
modules = ["sway"]
Niji will now output a sway configuration file to
~/.local/share/niji/sway/theme. To enable it, add the following line to the
bottom of your sway config:
include ~/.local/share/niji/sway/theme
If you want to override any of the settings exported by niji, you can simply add more configuration after the include statement.
Configuration
The following global configuration options are relevant to this module:
font_familyfont_scalecursor_themecursor_sizewallpaper
See Configuration for a detailed
explanation. In particular, see
Setting Wallpapers per Theme
for information on the wallpaper setting.
Additionally, these module-specific configuration options can be added to
config.toml (shown here with their default values):
[sway]
# Can be either "background", "surface", or "primary".
# This value determines which theme color is used for focused window borders.
focused_color = "surface"
# Can be either "background", "surface", "primary" or "secondary".
# This value determines which theme color is used for the indicator bar.
# Set to the same value as `focused_color` to hide the indicator entirely.
indicator_color = "surface"
Module swaylock
The swaylock module allows you to theme your
swaylock lock screen.
Activating
To activate the module, add it to your config.toml:
modules = ["swaylock"]
This will cause niji to take control of your .config/swaylock.config file.
Configuration
The following global configuration options are relevant for this module:
font_familyfont_scale
See Configuration for a detailed explanation.
Additionally, these module-specific configuration options can be added to
config.toml (shown here with their default values):
[swaylock]
# Set to a path string to set additional configuration options
custom_config_file = false
This module is only concerned with setting colors. Any additional configuration of swaylock, particularly if you are using something like swaylock-effects, needs to be done in a separate custom configuration file. An example configuration might look like this:
~/.config/niji/config.toml
# ...
[swaylock]
custom_config_file = "./custom/swaylock_config"
~/.config/niji/custom/swaylock_config
clock
indicator
grace=3
fade-in=1
Module waybar
The waybar module provides a fully managed waybar theme in line with your
system's niji theme.
Activating
To activate the module, add it to your config.toml:
modules = ["waybar"]
This will cause niji to take control of your .config/waybar/style.css file.
Configuration
The following global configuration options are relevant for this module:
font_familyfont_scale
See Configuration for a detailed explanation.
Additionally, these module-specific configuration options can be added to
config.toml (shown here with their default values):
[waybar]
# Set to the ids of custom modules that you use (e.g. "custom-gpu"),
# in order for them to be styled properly.
custom_modules = []
# Set to a string to specify a font to use for icons,
# such as FontAwesome or Material Desing icons
icon_font = false
# Set to false to disable shadows behind waybar elements
show_shadow = true
# The opacity of waybar when in a hidden state
hidden_opacity = 0.0
# The padding in pixels of waybar elements in the x direction.
padding_x = 12
# The padding in pixels of waybar elements in the y direction.
padding_y = 4
# The margin between workspace buttons in pixels
workspace_button_margin = 6
# Set to the path to a css file to include arbitrary custom styles
custom_style_file = false
Note, in particular, the custom_modules option. If you use custom modules, you
have to add them to the list, otherwise they won't be styled properly.
More Customization
Since waybar is, by its nature, highly customizable, this module is not going to
fit many people's use cases. You can try to fiddle around with the
custom_style_file configuration option, but if you already have a highly
customized waybar theme, I recommend you check out
Creating Custom Modules.
Module wob
The mako module allows you to theme
wob bars.
Activating
To activate the module, add it to your config.toml:
modules = ["wob"]
This will cause niji to take control of your .config/wob/wob.ini file.
Note that if you want live reloading to work, you will likely need to configure
a wob_command. See the following for details.
Configuration
These module-specific configuration options can be added to config.toml (shown
here with their default values):
[mako]
# The command used to start wob when reloading
wob_command = "tail -f $XDG_RUNTIME_DIR/wob.sock | wob"
# Set to a path string to specify custom values for wob.ini
custom_config_file = false
Due to the nature of how wob functions, it is likely necessary to customize the
wob_command option to get live reloading to function correctly. Simply set it
to the same command that you use to start wob initially.
Since niji needs to take control of .config/wob/wob.ini, if you want to set
any of wobs's additional configuration options, or override a value set by niji,
you'll have to create a separate configuration file in your .config/niji
directory, and link to it in config.toml. For example, if you wanted to show
the bar at the top of the screen, you might do something like this:
~/.config/niji/config.toml
# ...
[wob]
custom_config_file = "./custom/wob.ini"
~/.config/niji/custom/wob.ini
anchor = top
Custom Themes
If you build a custom theme, consider contributing it! Just make sure you have the proper license for the color scheme you're using, as color schemes may be subject to copyright.
Custom niji themes are defined using TOML files placed into
the ~/.config/niji/themes directory, with the filename (without the extension)
matching the theme name.
The file is split into two sections: [ui] for GUI colors, and [terminal] for
terminal colors. All colors are defined using #RRGGBB or #RRGGBBAA syntax.
[ui]
The [ui] section defines colors for graphical interfaces. It also contains the
option color_scheme, which should be either "light" or "dark" to tell GUI
toolkits whether the theme should be considered a light or a dark theme.
The section contains the following options:
| Option | Description |
|---|---|
color_scheme | Whether the theme should be considered light or dark. Takes only the values "light" and "dark". |
background | The main background color |
text_background | The color of text appearing on background |
surface | The background color of surfaces that appear on top of background (such as panels or cards) |
text_surface | The color of text appearing on surface |
primary | The primary accent color of the UI |
text_primary | The color of text appearing on primary |
secondary | The secondary accent color of the UI |
border | The color of borders around certain elements. May be set to transparent (#00000000) to remove borders. |
shadow | The color of drop shadow around certain elements. May be set to transparent (#00000000) to remove drop shadows. |
success | The color indicating a successful action. Usually a shade of green. |
text_success | The color of text appearing on success |
info | The color used for informative user feedback. May be set to the same as surface to remove the distinction. |
text_info | The color of text appearing on info. May be set to the same as text_surface to remove the distinction. |
warning | The color used for warning messages. Usually a shade of yellow or orange. |
text_warning | The color of text appearing on warning |
error | The color used for error messages and states. Usually a shade of red. |
text_error | The color of text appearing on error |
[terminal]
The [terminal] section contains color definitions corresponding to the
standard 16 ANSI colors:
blackredgreenyellowbluemagentacyanwhitebright_blackbright_redbright_greenbright_yellowbright_bluebright_magentabright_cyanbright_white
Example
The following is an example for a theme definition for the built-in tokyonight
theme:
[ui]
color_scheme = "dark"
background = "#1a1b26"
text_background = "#c0caf5"
surface = "#414868"
text_surface = "#c0caf5"
primary = "#a9b1d6"
text_primary = "#1a1b26"
secondary = "#73daca"
border = "#1a1b26"
shadow = "#10101080"
success = "#73daca"
text_success = "#e0af68"
info = "#7aa2f7"
text_info = "#1a1b26"
warning = "#e0af68"
text_warning = "#1a1b26"
error = "#f7768e"
text_error = "#1a1b26"
[terminal]
black = "#15161e"
red = "#f7768e"
green = "#9ece6a"
yellow = "#e0af68"
blue = "#7aa2f7"
magenta = "#bb9af7"
cyan = "#7dcfff"
white = "#a9b1d6"
bright_black = "#414868"
bright_red = "#f7768e"
bright_green = "#73daca"
bright_yellow = "#e0af68"
bright_blue = "#7aa2f7"
bright_magenta = "#bb9af7"
bright_cyan = "#7dcfff"
bright_white = "#c0caf5"
Custom Modules
If you build a custom module, consider contributing it! PRs are always welcome :)
Custom modules are located in the directory ~/.config/niji/modules. Each
module is a folder in that directory; the name of the folder is the module name.
The heart of a niji module is a lua module in the module folder called
module.lua. It has this general structure:
local M = {}
function M.apply(config, theme)
-- Apply the theme here
end
function M.reload(config)
-- Reload the application here.
end
return M
The module defines two handlers, apply and reload.
The apply handler receives the module config and the
theme as parameters. It is responsible for taking the theme,
transforming its contents and writing them to where they need to go for the
theming target to use them.
The reload handler is optional. It is responsible for reloading the theming
target to apply the new config. The reason why these two are separate is so that
niji can more easily tell which modules support live reloading, and so that
users can selectively disable live reloading for certain modules.
The exact semantics of the two handlers are different depending on the nature of
the theming target, but in general, apply should apply the theme and config in
the least invasive way possible, while reload does whatever is necessary to
live-reload the theming target.
Module Config
The module config, which is passed as the first parameter to both the apply
and the reload handlers, is a table with string keys and arbitrary values. It
comes from combining the module-specific configuration for your module with the
global module configuration, both of which are defined in config.toml. See
Configuration for more information.
Simple modules for personal use probably won't use this feature much, but it is
recommended that modules which are used by multiple users and may be merged to
be builtin modules use the config feature to provide options to users, and
conform to certain global configuration options like font_scale.
Theme
The theme is a table that corresponds directly to the theme format documented in
Custom Themes. All color values in the theme table are
passed as a niji.Color instance.
Lua API
Niji provides its own Lua API for building modules. It is fully documented in the section Lua API Reference.
Templates
A very common thing that modules need to do is inserting some values from the
theme into a pre-made config file template. niji provides a builtin system to do
this, which is documented in the section
Templating Reference, and can be used via the
niji.Template class from the Lua
API.
Lua API Reference
niji's Lua API resides in the global niji namespace. There is no need to
import it. The niji namespace contains several sub-namespaces and classes for
different purposes, which are listed in this document.
In addition, you can always use the Lua standard library which is fully supported. If one of the functions in the niji API fits what you want to do however, you should always prefer using the niji API, as it provides better integration and safety features.
Modules are always executed with their working directory inside of their module folder, so you can easily reference bundled assets like template files using relative paths.
Contents:
- Class
niji.Color - Class
niji.Template - Namespace
niji.console - Namespace
niji.fs - Namespace
niji.mod - Namespace
niji.os - Namespace
niji.util - Namespace
niji.xdg
Class niji.Color
The class niji.Color represents an RGBA color. It can be used to perform
certain manipulations on colors. All color manipulations use the Oklab
perceptual color space, so while some results may appear unexpected through an
RGB lens, they should look good.
All color fields in the theme parameter of the module application handler are
also instances of niji.Color.
All functions that accept colors also accept strings of the format "#RRGGBB"
and "#RRGGBBAA".
Property niji.Color.r
The red channel of the color as an integer between 0 and 255
Property niji.Color.g
The green channel of the color as an integer between 0 and 255
Property niji.Color.b
The blue channel of the color as an integer between 0 and 255
Property niji.Color.a
The alpha channel of the color as an integer between 0 and 255
Static niji.Color:new(color_string)
Constructs a new niji.Color object.
color_string: A string representing the desired color (string)- returns: The resulting color (
niji.Color)
local my_color = niji.Color:new("#ab38a3ff")
-- Prints "#ab3aa3ff"
niji.console.debug(my_color)
Static niji.Color:blend(color_1, color_2, t)
Interpolates between two colors.
color_1: The first of the two colors to interpolate between (stringorniji.Color)color_2: The second of the two colors to interpolate between (stringorniji.Color)t: A number between 0 and 1 that controls the interpolation (float)- returns: The resulting color (
niji.Color)
local my_color = niji.Color:blend("#ff0000", "#00ff00", 0.3)
-- Prints "#ff6300ff"
niji.console.debug(my_color)
Static niji.Color:mix(color_1, color_2)
Mixes two colors together evenly. Equivalent to calling niji.Color:blend with
a t of 0.5.
color_1: The first of the two colors to mix together (stringorniji.Color)color_2: The second of the two colors to mix together (stringorniji.Color)
local my_color = niji.Color:mix("#ff0000", "#00ff00")
-- Prints "#f99500ff"
niji.console.debug(my_color)
niji.Color:lighten(amount)
Lightens the color by the given amount. "Amount" here refers to relative perceived lightness, which means that the change in lightness for a given amount parameter should look the same for any base color, unless the resulting color would fall outside the RGB color gamut.
amount: The desired relative perceived lightness, ranging between -1 and 1 (float)
local base_color = niji.Color:new("#123faa")
local lightened_color = base_color:lighten(0.2)
-- Prints "#4a7eeeff"
niji.console.debug(lightened_color)
niji.Color:darken(amount)
Darkens the color by the given amount. Equivalent to calling
niji.Color:lighten with -amount.
amount: The desired relative perceived lightness, ranging between -1 and 1 (float)
local base_color = niji.Color:new("#c670f9")
local lightened_color = base_color:darken(0.2)
-- Prints "#872eb5ff"
niji.console.debug(lightened_color)
niji.Color:shade(lightness)
Selects a shade of the color that has the provided absolute perceived lightness. As with other operations, if that color falls outside the RGB gamut, it gets gamut-clipped.
lightness: The desired perceived lightness, ranging between 0 and 1 (float)
local base_color = niji.Color:new("#cb9174")
local shade = base_color:shade(0.4)
-- Prints "#6c3a1fff"
niji.console.debug(shade)
niji.Color:with_alpha(alpha)
Returns the same color with the provided alpha value.
alpha: The desired alpha value, ranging between 0 and 1 (float)
local base_color = niji.Color:new("#abcdef")
local transparent_color = base_color:with_alpha(0.5)
-- Prints "#abcdef80"
niji.console.debug(transparent_color)
Class niji.Template
The class niji.Template is the lua API for niji's builtin
templating system. It can be used to load, parse
and render templates.
Static niji.Template:parse(template)
Parses the provided string template as a template.
template: The template string (string)- returns: The parsed template object (
niji.Template)
local my_template = niji.Template:parse("Hello {{name}}!")
Static niji.Template:load(path)
A utility method that loads a template from a file.
path: The path to the template file to load (string)- returns: The parsed template object (
niji.Template)
local my_template = niji.Template:load("my_template.mustache")
niji.Template:render(value)
Render the template to a string using a given input value. This is most commonly a table of keys and values used in the template.
value: The value to use as an input in the template (any type)- returns: The rendered string (
string)
local my_template = niji.Template:parse("Hello {{name}}!")
local rendered = my_template:render({ name = "World" })
-- prints "Hello World!"
niji.console.debug(rendered)
niji.Template:set_format(type_name, format_string)
Set the custom format for the specified type. See the template system reference for more information.
type_name: The name of the type for which to set the format (string)format_string: The format string to use for the given type
Namespace niji.console
The niji.console namespace provides niji-flavored functions for interacting
with the console.
niji.console.debug(message)
Sends a debug message to the console. Note that these messages are only visible
if --verbose is passed as an argument to niji.
message: The message to send (any type)
niji.console.info(message)
Sends an info message to the console.
message: The message to send (any type)
niji.console.warn(message)
Sends a warning message to the console.
message: The message to send (any type)
niji.console.error(message)
Sends an error message to the console.
message: The message to send (any type)
niji.console.prompt(message, default)
Sends a confirmation prompt to the user. If default is not nil, pressing enter
without entering a response will return that value. If default is nil,
pressing enter without entering a response will trigger a reprompt.
prompt: The message to show in the prompt (any type)default: The default value for the prompt (boolornil)- returns: The response from the user (
bool)
if niji.console.prompt("Do the thing?", true) then
doTheThing()
end
Namespace niji.fs
The namespace niji.fs contains functions for interacting with the file system.
While it is much more restrictive than the filesystem API built into lua, it is
strongly recommended to use niji.fs functions over raw lua functions whenever
possible, because they have a lot of extra safety features, such as
automatically checking for conflicts with preexisting files.
niji.fs.write(path, content)
This function should be used when you have to write to a file that might already exist on the system, and which you might not want to silently overwrite if it does; the major example for this is configuration files which don't support including files from other locations.
If you just want to output a file that can then be included/imported by another
program, consider using niji.fs.output. This is often a better approach,
because it is a lot less invasive.
Calling niji.fs.write will cause niji to check if the file already exists, and
contains data that wasn't written to it by niji. If that is the case, niji will
inform the user via a prompt, and create a backup of the previous version if
necessary. Ultimately, it writes content to file at the given path.
path: The path of the file to write to (string). You can use "~" to refer to the current user's home directory.content: The string to write to the file (string)- returns: The absolute, canonical path of the file written to (
string)
niji.fs.write_config(path, content)
A version of niji.fs.write that takes paths relative to ~/.config.
path: The relative path to the config file to write to (string)content: The content to write to the file (string)- returns: The absolute, canonical path of the file written to (
string)
niji.fs.write_state(path, content)
A version of niji.fs.write that takes paths relative to ~/.local/state.
path: The relative path of the state file to write to (string)content: The content to write to the file (string)- returns: The absolute, canonical path of the file written to (
string)
niji.fs.write_data(path, content)
A version of niji.fs.write that takes path relative to ~/.local/share.
path: The relative path of the data file to write to (string)content: The content to write to the file (string)- returns: The absolute, canonical path of the file written to (
string)
niji.fs.output_artifact(config, opts)
Outputs a file to the module's output directory, and validates that it is included in a specified config file. Prints a warning if this is not the case.
config: the module config passed to theapplyfunctionopts: a table of options:out: the file path to output to, relative to your module's output folder, by default located at~/.local/share/niji/<module name>content: the string to write to the output filesourced_by_config: the config file (or list of config files) that theoutfile is expected to be sourced or included by. The path is relative to~/.config(or$XDG_CONFIG_HOME).sourced_by_path: use instead ofsourced_by_configif you need to specify arbitrary paths that aren't relative to the systems config home.pattern: lua regex pattern that the config files are matched against to check if they're including the output file properlyline_pattern: likepattern, except the matching is done line-by-line.hint: example of how to properly include the output file in the config file
niji.fs.output_unchecked(path, content)
Outputs a file to the module's output directory without performing further checks.
If the output file is crucial for this module to function, consider using
niji.fs.output_artifact instead.
The path argument for this functions is relative to your module's output
folder, which, by default, is located at ~/.local/share/niji/<module name>.
path: The relative path of the output file within the output folder (string)content: The content to write to the file (string)- returns: The absolute path of the file that was written to (
string)
niji.fs.get_output_dir()
Returns the directory that niji.fs.output places files into.
- returns: the output directory
niji.fs.read_config_asset(path)
Reads a file with a path relative to .config/niji. This is often used for
things like supplementary configuration files that get inserted into the
generated config of a module, as used in the mako module for example.
path: The relative path of the asset file within the config folder (string)- returns: The contents of the file (
string)
niji.fs.read_config(path)
Reads a file with a path relative to ~/.config.
path: The relative path of the config file (string)- returns: The contents of the file (
string)
niji.fs.read_state(path)
Reads a file with a path relative to ~/.local/state.
path: The relative path of the state file (string)- returns: The contents of the file (
string)
niji.fs.read_data(path)
Reads a file with a path relative to ~/.local/share.
path: The relative path of the state file (string)- returns: The contents of the file (
string)
Namespace niji.mod
The namespace niji.mod can be used to obtain metadata about the current
module.
niji.mod.name
The name of the current module (string)
niji.mod.path
The absolute path to the module folder of the current module (string)
Namespace niji.os
The namespace niji.os contains supplementary functions to the "os"
functionality in lua.
niji.os.exec_detached(command)
Behaves like the builtin os.exec function in lua, except it detaches the
command from the parent process, allowing it to keep running in the background
after niji has completed execution.
You should use this method if you want to restart a background process with updated configuration, for example.
command: The command to execute in the background (string)
Namespace niji.util
The namespace niji.util implements functions for a couple of common, specific
operations.
niji.util.font_size(config, default)
This function allows modules to easily handle the global font_scale option. If
you output a font size to somewhere, simply pass it through this function to
allow the user to scale their system font to their liking.
config: The module configuration passed to the module handlersdefault: The font size to use if the scale is 1.0 (int)- returns: The properly scaled font size (
int)
function M.apply(config, theme)
local my_font_size = niji.util.font_size(config, 12)
-- ...
end
niji.util.by_theme(theme, value)
This function makes it easy to allow a config option to optionally be set for
each theme individually. The archetypical use case is modules with wallpaper
support handling the global wallpaper config option.
The logic itself is fairly simple; if value is a table, return
value[<theme name>], or value.default if that is not set. Otherwise, just
return value itself.
theme: The theme passed to the apply handlervalue: The config value to handle
function M.apply(config, theme)
local selected_wallpaper = niji.util.by_theme(theme, config.wallpaper)
-- ...
end
Namespace niji.xdg
The namespace niji.xdg provides bindings to the configured locations for the
XDG base directories standard.
niji.xdg.config_home
$XDG_CONFIG_HOME, or $HOME/.config by default. (string)
niji.xdg.data_home
$XDG_DATA_HOME, or $HOME/.local/share by default. (string)
niji.xdg.state_home
$XDG_STATE_HOME, or $HOME/.local/state by default. (string)
niji.xdg.cache_home
$XDG_CACHE_HOME, or $HOME/.cache by default. (string)
niji.xdg.runtime_dir
The value of $XDG_RUNTIME_DIR. (string)
niji.xdg_data_dirs
The paths contained in $XDG_DATA_DIRS, or
{ "/usr/local/share", "/usr/share" } by default. (string[])
niji.xdg_config.dirs
The paths contained in $XDG_CONFIG_DIRS, { "/etc/xdg" } by default.
(string[])
Templating reference
niji has builtin support for templating using its
niji.Template API.
The templating language used for this is niji's own dialect of mustache. You can look at the mustache documentation for general information on how it works, it mostly applies to niji's dialect as well.
One major difference from the mustache specification is that triple mustaches
({{{name}}}), which are normally used to disable escaping of HTML characters,
are not supported. Instead, niji templates just never escape HTML characters.
Custom Formats
The one extension that niji makes to the base mustache specification is custom formats for complex types. niji's mustache dialect provides special syntax for displaying formattable types using format strings. This feature is necessary because the vast array of targets niji supports may expect vastly different formats for different data types, and it is impractical to split those data types up into more atomic parts.
For example, you can render a color using a custom format like this:
{{my_color : "🔴{r}🟢{g}🔵{b}"}}
The result of rendering this with my_color = "#abcdefff" would be
🔴171🟢205🔵239.
Often times, you will want to use a specific format for the entirety of a template. You can do this by adding a format specification for the type name at the top of your file like this:
{{% "color" : "rgba({r}, {g}, {b}, {a})" %}}
.some-class {
background-color: {{my_color}}
}
The general format for format strings is exactly the same as that which is used by Rust's standard library, and you can insert any of the properties defined for the type you're working with. A list can be found in the following section.
Formattable Types
For now, the only formattable type is niji.Color. It exposes the following
properties:
| Name | Description |
|---|---|
r | The red component as an integer between 0 and 255 |
g | The green component as an integer between 0 and 255 |
b | The blue component as an integer between 0 and 255 |
a | The alpha component as an integer between 0 and 255 |
rx | The red component as two hexadecimal digits |
gx | The green component as two hexadecimal digits |
bx | The blue component as two hexadecimal digits |
ax | The alpha component as two hexadecimal digits |
rf | The red component as a float between 0 and 1 |
gf | The green component as a float between 0 and 1 |
bf | The blue component as a float between 0 and 1 |
af | The alpha component as a float between 0 and 1 |