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 avaliable 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 selcted 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-frappe
catpuccin-latte
dracula
gruvbox
gruvbox-light
tokyonight
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 environent 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_theme
cursor_size
font_family
font_scale
See Configuration for a detailed explanation. Note that these options do not work if reloads are disabled for this module.
Additionaly, 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_theme
cursor_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"
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).
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_family
font_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_family
font_scale
cursor_theme
cursor_size
wallpaper
See Configuration for a detailed explanantion. 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_family
font_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_family
font_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 somethin
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:
black
red
green
yellow
blue
magenta
cyan
white
bright_black
bright_red
bright_green
bright_yellow
bright_blue
bright_magenta
bright_cyan
bright_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 addution, 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 (string
orniji.Color
)color_2
: The second of the two colors to interpolate between (string
orniji.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 (string
orniji.Color
)color_2
: The second of the two colors to mix together (string
orniji.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 (bool
ornil
)- 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(path, content)
This function should be used if you want to output a file that is then actively imported/included
by another program. An example for this is the hyprland module, which outputs a partial hyprland config file
which you can then include in your config. In many cases, this is the recommended approach over niji.fs.write
,
because it is less invasive and makes it easier to manage separate config options. Which approach fits each module
better is up to the disgression of the module author however.
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 folde (string
)content
: The content to write to the file (string
)- returns: The absolute path of the file that was written to (
string
)
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 impractial to split those datatypes 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 |