361 lines
15 KiB
Markdown
361 lines
15 KiB
Markdown
# Keymap
|
|
|
|
Keymap is a searchable, theme-aware shortcut viewer and editor for Noctalia.
|
|
It supports Hyprland's native Lua configuration, Niri, and MangoWC, follows
|
|
split configuration files, and preserves user-defined categories.
|
|
|
|

|
|
|
|
## Features
|
|
|
|
- Reads the active compositor automatically, with a manual override for custom
|
|
sessions and test setups.
|
|
- Searches shortcut descriptions, combinations, categories, actions, commands,
|
|
and MangoWC key modes.
|
|
- Renders ANSI 100%, 96%, 80% (TKL), 75%, 65%, and 60% keyboards.
|
|
- Shows whether a physical key is free, occupied on the selected modifier
|
|
layer, or used by another combination.
|
|
- Creates press and release shortcuts where the compositor supports them.
|
|
- Browses Noctalia IPC commands and native actions for the active compositor,
|
|
with source, category, readiness, and text filters.
|
|
- Includes a searchable library of Noctalia commands and native compositor
|
|
actions, while retaining free-form custom shell commands.
|
|
- Edits supported combinations, descriptions, commands, trigger modes, and
|
|
categories directly above the shortcut list.
|
|
- Reorders shortcuts and moves them between categories with drag and drop.
|
|
- Renames categories and can hide, restore, or permanently delete shortcuts.
|
|
- Uses Noctalia theme roles by default and accepts custom colors for cards,
|
|
headings, modifier pills, keys, and text.
|
|
- Validates and reloads configuration changes, with guarded rollback on
|
|
failure.
|
|
|
|

|
|
|
|
## Plugin
|
|
|
|
| Type | ID |
|
|
| --- | --- |
|
|
| Bar widget | `widget` |
|
|
| Panel | `panel` |
|
|
| Hyprland service | `service` |
|
|
| Niri service | `niri-service` |
|
|
| MangoWC service | `mangowc-service` |
|
|
| Configuration writer | `writer-service` |
|
|
|
|
The complete plugin ID is `blackbartblues/keymap`.
|
|
|
|
## Requirements
|
|
|
|
- Noctalia v5 with plugin API 5.
|
|
- Hyprland with its native Lua configuration API, Niri, or MangoWC.
|
|
- The command-line tools for the selected compositor, plus `xdg-open` for the
|
|
optional configuration-folder action: Hyprland uses `hyprctl` and
|
|
`Hyprland`; Niri uses `niri`; MangoWC uses `mango` and `mmsg`.
|
|
|
|
Classic Hyprland `.conf` keybinds are intentionally unsupported. Hyprland is
|
|
moving to its native Lua configuration API, which is the only Hyprland format
|
|
Keymap reads and writes.
|
|
|
|
For read-only use, Niri and MangoWC are parsed without spawning their IPC
|
|
tools. The validator and reload commands are used only after an explicit edit.
|
|
The folder button uses `xdg-open` to open the directory containing the active
|
|
configuration file.
|
|
|
|
## Usage
|
|
|
|
Add the `widget` entry to a Noctalia bar and click it, or open the panel through
|
|
IPC:
|
|
|
|
```sh
|
|
noctalia msg panel-toggle blackbartblues/keymap:panel
|
|
```
|
|
|
|
The header provides keyboard and list views, the shortcut creator, the
|
|
existing-shortcut editor, refresh, configuration-folder, settings, and close
|
|
actions.
|
|
|
|
The settings button opens `Settings -> Plugins`. Select the gear beside
|
|
Keymap to edit its compositor, paths, keyboard size, columns, and colors.
|
|
|
|
## Configuration discovery
|
|
|
|
An existing path entered in Keymap settings always wins. If that path does not
|
|
exist, Keymap searches safe, compositor-specific locations:
|
|
|
|
- Hyprland: `$XDG_CONFIG_HOME/hypr/hyprland.lua`, `init.lua`, and
|
|
`/etc/xdg/hypr/hyprland.lua`, followed by a scored scan of top-level `.lua`
|
|
files in the Hyprland configuration directory.
|
|
- Niri: `$NIRI_CONFIG`, `$XDG_CONFIG_HOME/niri/config.kdl`, followed by a
|
|
scored scan of top-level `.kdl` files in the Niri configuration directory.
|
|
- MangoWC: `$XDG_CONFIG_HOME/mango/config.conf`, `/etc/mango/config.conf`,
|
|
followed by a scored scan of top-level `.conf` files in the MangoWC
|
|
configuration directory.
|
|
|
|
The generated `keymap.lua`, `keymap.kdl`, and `keymap.conf` files and files
|
|
whose names contain `backup` are excluded from automatic discovery. If no
|
|
usable shortcut file is found, the panel points to settings so the correct path
|
|
can be entered manually.
|
|
|
|
## Browsing shortcuts
|
|
|
|
In keyboard view, enable an exact Super, Ctrl, Shift, and Alt layer. Occupied
|
|
keys open the shortcuts assigned to that combination; unoccupied keys can be
|
|
sent directly to the creator. Change the physical layout from the keyboard
|
|
size selector while editing shortcuts, or set its default in plugin settings.
|
|
When a key is occupied in another modifier layer, select it and use the layer
|
|
buttons in the details card to jump directly to the matching combination.
|
|
|
|
In list view, type into the search box to filter the complete category tree.
|
|
Sequential shortcuts such as workspaces 1 through 9 can optionally be folded
|
|
into a single row.
|
|
|
|
The example configurations below demonstrate the same feature set without
|
|
reading or modifying a personal setup:
|
|
|
|

|
|
|
|

|
|
|
|
## Creating shortcuts
|
|
|
|
Select **New shortcut**, choose modifiers and a key, select an existing or new
|
|
category, then enter a description and command. The keyboard view can fill the
|
|
combination by clicking a physical key.
|
|
|
|
Select **Commands** beside the command field to open the known-command
|
|
library. It contains every command exposed by Noctalia's IPC help plus the
|
|
native Hyprland Lua, Niri KDL, or MangoWC actions for the active compositor.
|
|
Filter by source, category, whether an action still needs arguments, or free
|
|
text. Selecting an entry fills the command field; replace every
|
|
`{{placeholder}}` with a compositor-valid value before saving. **Custom
|
|
command** returns to an unrestricted shell command, so the library never
|
|
removes the option to type a command manually.
|
|
|
|
Native actions are offered while creating a shortcut. In the editor, the
|
|
library offers Noctalia shell commands only: converting an existing shell bind
|
|
to a different native syntax cannot be rewritten safely across all supported
|
|
source forms.
|
|
|
|
Hyprland supports multi-key sequences such as `Super + C + V`. Niri and
|
|
MangoWC accept one ordinary key in this writer. Niri exposes press activation;
|
|
Hyprland and MangoWC expose press and release activation.
|
|
|
|

|
|
|
|
### Command library
|
|
|
|
Select **Command library** beside the command field to browse 362 known
|
|
commands and native actions:
|
|
|
|
| Source | Entries | Verified from |
|
|
| --- | ---: | --- |
|
|
| Noctalia | 98 | Runtime `noctalia msg --help` output |
|
|
| Hyprland | 51 | Native `hl.dsp.*` dispatcher bindings from Hyprland 0.56.0 |
|
|
| Niri | 135 | Configurable KDL actions from Niri 26.04 |
|
|
| MangoWC | 78 | Current parser dispatchers and official keybinding documentation |
|
|
|
|
Search by action, syntax, source, or category. Source, category, and readiness
|
|
filters can narrow the results. **Ready** entries can be inserted directly;
|
|
**Needs input** entries contain visible `{{argument}}` placeholders that must
|
|
be replaced before saving. Selecting **Custom command** returns to a normal
|
|
shell command without restricting it to the catalog.
|
|
|
|
Noctalia entries are saved as shell commands. When creating a shortcut,
|
|
compositor entries are emitted as native Hyprland Lua, Niri KDL, or MangoWC
|
|
actions rather than wrappers around an IPC command. The writer checks the
|
|
selected entry ID, compositor, source, and completed template again before it
|
|
touches a file. Existing native actions remain preserved but are not converted
|
|
to another native catalog action by the editor.
|
|
|
|

|
|
|
|
The first created shortcut adds one marked include to the configured root and
|
|
creates a sibling managed file:
|
|
|
|
| Compositor | Managed file | Marked include |
|
|
| --- | --- | --- |
|
|
| Hyprland | `keymap.lua` | `require("keymap")` |
|
|
| Niri | `keymap.kdl` | `include "keymap.kdl"` |
|
|
| MangoWC | `keymap.conf` | `source=./keymap.conf` |
|
|
|
|
## Editing and organizing
|
|
|
|
Select **Edit shortcuts** to expose actions on writable rows. The pencil opens
|
|
the inline editor above the category cards. The eye-slash action hides a
|
|
shortcut without losing its original text, and the trash action permanently
|
|
deletes it after confirmation. Hidden shortcuts remain available in the
|
|
editor's recovery section, where they can be restored or deleted.
|
|
|
|
Drag a row handle to another position in the same category or into another
|
|
category. The same move can be performed with the Category field in the inline
|
|
editor. Select the pencil in a category heading to rename that category.
|
|
|
|
Native compositor actions remain intact. Fields that cannot be rewritten
|
|
safely are disabled instead of being guessed. Generated, ranged, or otherwise
|
|
read-only entries are visibly locked.
|
|
|
|
Before every create, update, move, reorder, category rename, hide, restore, or
|
|
delete operation, Keymap verifies that the source still matches the parsed
|
|
snapshot and refuses symbolic-link targets. Writes use a temporary sibling and
|
|
atomic rename. The candidate is then checked with the compositor's native
|
|
validator and reloaded:
|
|
|
|
| Compositor | Validator | Reload |
|
|
| --- | --- | --- |
|
|
| Hyprland | `Hyprland --verify-config -c <file>` | `hyprctl reload` |
|
|
| Niri | `niri validate -c <file>` | `niri msg action load-config-file` |
|
|
| MangoWC | `mango -c <file> -p` | `mmsg dispatch reload_config` |
|
|
|
|
If validation or reload fails, Keymap attempts to restore each file it changed.
|
|
After a reload failure, it also attempts to reload the restored configuration.
|
|
Rollback or recovery-reload failures are reported explicitly. A source that
|
|
changes after parsing is never overwritten; the operation stops and asks the
|
|
user to refresh instead.
|
|
|
|
## Categories and source formats
|
|
|
|
### Hyprland Lua
|
|
|
|
Place numbered headings before groups of native Lua bindings:
|
|
|
|
```lua
|
|
-- 1. Applications
|
|
hl.bind("SUPER + RETURN", hl.dsp.exec_cmd("foot"), { description = "Open terminal" })
|
|
```
|
|
|
|
Local modules loaded with `require` are scanned recursively. Literal
|
|
descriptions and literal prefixes such as `description = "Workspace " .. i`
|
|
are matched against the live bind registry. The live registry remains
|
|
authoritative; the Lua files supply source locations, editable snippets, and
|
|
category order.
|
|
|
|
Hyprland versions whose `hyprctl binds -j` output cannot be decoded are handled
|
|
automatically through the complete plain-text `hyprctl binds` fallback.
|
|
|
|
### Niri
|
|
|
|
Category comments live inside `binds {}` blocks:
|
|
|
|
```kdl
|
|
binds {
|
|
// #"Applications"
|
|
Mod+Return hotkey-overlay-title="Open terminal" { spawn-sh "foot"; }
|
|
}
|
|
```
|
|
|
|
Positional `include` nodes, optional includes, later overrides, disabled `/-`
|
|
nodes, custom overlay titles, and native actions are supported. Because Niri
|
|
does not expose an effective bind registry through IPC, its configuration tree
|
|
is the source of truth.
|
|
|
|
### MangoWC
|
|
|
|
Category comments and optional descriptions use the following form:
|
|
|
|
```ini
|
|
# Applications
|
|
bind=SUPER,Return,spawn_shell,foot #"Open terminal"
|
|
```
|
|
|
|
Keymap supports `bind` with `l/s/r/p` flags, `axisbind`, `mousebind`,
|
|
`gesturebind`, `switchbind`, `keymode`, `source`, and `source-optional`.
|
|
MangoWC's configuration tree is the source of truth.
|
|
|
|
Complete, non-loaded examples are included in the repository:
|
|
|
|
- [`examples/hyprland.lua`](examples/hyprland.lua) — 40 shortcuts and a config
|
|
that passes `Hyprland --verify-config`.
|
|
- [`examples/niri.kdl`](examples/niri.kdl) — 39 shortcuts and a config that
|
|
passes `niri validate`.
|
|
- [`examples/mangowc.conf`](examples/mangowc.conf) — 40 shortcuts.
|
|
|
|
They cover applications, window management, workspaces, screenshots, Noctalia,
|
|
media controls, utilities, release triggers, wheel bindings, and compositor
|
|
native actions. They are documentation and test fixtures; Keymap never loads
|
|
them automatically.
|
|
|
|
## Settings
|
|
|
|
| Setting | Default | Purpose |
|
|
| --- | --- | --- |
|
|
| `compositor` | `auto` | Detect the session or force Hyprland, Niri, or MangoWC. |
|
|
| `hyprland_config` | `~/.config/hypr/hyprland.lua` | Hyprland native Lua root. |
|
|
| `niri_config` | `~/.config/niri/config.kdl` | Niri KDL root. |
|
|
| `mangowc_config` | `~/.config/mango/config.conf` | MangoWC config root. |
|
|
| `merge_sequential` | `true` | Fold related numbered shortcuts into one row. |
|
|
| `show_undescribed` | `true` | Show Hyprland binds without descriptions. |
|
|
| `keyboard_layout` | `100` | Default 100%, 96%, 80%, 75%, 65%, or 60% view. |
|
|
| `columns` | `3` | One to four balanced category columns. |
|
|
| `card_color` / `card_opacity` | `surface_variant` / `35` | Card background role or custom color and opacity. |
|
|
| `category_color` | `primary` | Category heading role or custom color. |
|
|
| `description_color` | `on_surface` | Description role or custom color. |
|
|
| modifier color pairs | Noctalia theme roles | Background and text for Super, Ctrl, Shift, and Alt. |
|
|
| `key_color` / `key_text_color` | `surface` / `on_surface` | Ordinary key background and text. |
|
|
| widget `glyph` / `show_label` | `keyboard` / `false` | Bar appearance. |
|
|
|
|

|
|
|
|
Theme-role values follow Noctalia palette changes automatically. Every color
|
|
setting also accepts a custom color.
|
|
|
|
## IPC
|
|
|
|
Request an immediate refresh from the service for the active compositor:
|
|
|
|
```sh
|
|
# Hyprland
|
|
noctalia msg plugin blackbartblues/keymap:service all refresh
|
|
|
|
# Niri
|
|
noctalia msg plugin blackbartblues/keymap:niri-service all refresh
|
|
|
|
# MangoWC
|
|
noctalia msg plugin blackbartblues/keymap:mangowc-service all refresh
|
|
```
|
|
|
|
The panel accepts `view-keyboard`, `view-list`, `creator-open`,
|
|
`creator-cancel`, `editor-open`, `editor-bind <bind-id>`, `clear-modifiers`,
|
|
`keyboard-key <key>`, and `keyboard-layout <layout>` events. For example:
|
|
|
|
```sh
|
|
noctalia msg plugin blackbartblues/keymap:panel all keyboard-layout 75
|
|
```
|
|
|
|
Valid layout payloads are `100`, `96`, `80`, `75`, `65`, and `60`.
|
|
|
|
## Safety and limits
|
|
|
|
- Keymap makes no network requests and never executes commands stored inside
|
|
shortcuts; it only passes explicitly saved configuration text to the active
|
|
compositor.
|
|
- Configuration traversal is cycle-safe and limited to 64 files of up to
|
|
512 KiB each. Root files accepted for writing are limited to 2 MiB.
|
|
- Required missing Niri includes and MangoWC sources stop parsing rather than
|
|
silently presenting an incomplete list. Optional sources and non-fatal
|
|
parser issues are shown as warnings.
|
|
- All interface prose and settings metadata use Noctalia's translation API.
|
|
Physical key legends and standard modifier names remain technical labels.
|
|
The shipped English catalog is the source language for Weblate.
|
|
|
|
## Tests
|
|
|
|
From the `keymap` directory:
|
|
|
|
```sh
|
|
for test_file in tests/*.lua; do lua "$test_file"; done
|
|
python tests/command_library_test.py
|
|
python tests/i18n_test.py
|
|
Hyprland --verify-config -c examples/hyprland.lua
|
|
niri validate -c examples/niri.kdl
|
|
```
|
|
|
|
The suite covers category markers, hidden-block recovery, Hyprland command
|
|
parsing and text fallback, all keyboard layouts, create/update/write rollback,
|
|
the three example configurations, command-library integrity and native action
|
|
creation, short DnD identifiers, automatic path discovery, and translation-key
|
|
coverage.
|
|
|
|
## License
|
|
|
|
MIT.
|