1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00
Files
DankMaterialShell/core/internal/keybinds/providers/niri.go
2025-11-30 19:25:48 -05:00

138 lines
3.4 KiB
Go

package providers
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/AvengeMedia/DankMaterialShell/core/internal/keybinds"
)
type NiriProvider struct {
configDir string
}
func NewNiriProvider(configDir string) *NiriProvider {
if configDir == "" {
configDir = defaultNiriConfigDir()
}
return &NiriProvider{
configDir: configDir,
}
}
func defaultNiriConfigDir() string {
configHome := os.Getenv("XDG_CONFIG_HOME")
if configHome != "" {
return filepath.Join(configHome, "niri")
}
home, err := os.UserHomeDir()
if err != nil {
return ""
}
return filepath.Join(home, ".config", "niri")
}
func (n *NiriProvider) Name() string {
return "niri"
}
func (n *NiriProvider) GetCheatSheet() (*keybinds.CheatSheet, error) {
section, err := ParseNiriKeys(n.configDir)
if err != nil {
return nil, fmt.Errorf("failed to parse niri config: %w", err)
}
categorizedBinds := make(map[string][]keybinds.Keybind)
n.convertSection(section, "", categorizedBinds)
return &keybinds.CheatSheet{
Title: "Niri Keybinds",
Provider: n.Name(),
Binds: categorizedBinds,
}, nil
}
func (n *NiriProvider) convertSection(section *NiriSection, subcategory string, categorizedBinds map[string][]keybinds.Keybind) {
currentSubcat := subcategory
if section.Name != "" {
currentSubcat = section.Name
}
for _, kb := range section.Keybinds {
category := n.categorizeByAction(kb.Action)
bind := n.convertKeybind(&kb, currentSubcat)
categorizedBinds[category] = append(categorizedBinds[category], bind)
}
for _, child := range section.Children {
n.convertSection(&child, currentSubcat, categorizedBinds)
}
}
func (n *NiriProvider) categorizeByAction(action string) string {
switch {
case action == "next-window" || action == "previous-window":
return "Alt-Tab"
case strings.Contains(action, "screenshot"):
return "Screenshot"
case action == "show-hotkey-overlay" || action == "toggle-overview":
return "Overview"
case action == "quit" ||
action == "power-off-monitors" ||
action == "toggle-keyboard-shortcuts-inhibit" ||
strings.Contains(action, "dpms"):
return "System"
case action == "spawn":
return "Execute"
case strings.Contains(action, "workspace"):
return "Workspace"
case strings.HasPrefix(action, "focus-monitor") ||
strings.HasPrefix(action, "move-column-to-monitor") ||
strings.HasPrefix(action, "move-window-to-monitor"):
return "Monitor"
case strings.Contains(action, "window") ||
strings.Contains(action, "focus") ||
strings.Contains(action, "move") ||
strings.Contains(action, "swap") ||
strings.Contains(action, "resize") ||
strings.Contains(action, "column"):
return "Window"
default:
return "Other"
}
}
func (n *NiriProvider) convertKeybind(kb *NiriKeyBinding, subcategory string) keybinds.Keybind {
key := n.formatKey(kb)
desc := kb.Description
rawAction := n.formatRawAction(kb.Action, kb.Args)
if desc == "" {
desc = rawAction
}
return keybinds.Keybind{
Key: key,
Description: desc,
Action: rawAction,
Subcategory: subcategory,
}
}
func (n *NiriProvider) formatRawAction(action string, args []string) string {
if len(args) == 0 {
return action
}
return action + " " + strings.Join(args, " ")
}
func (n *NiriProvider) formatKey(kb *NiriKeyBinding) string {
parts := make([]string, 0, len(kb.Mods)+1)
parts = append(parts, kb.Mods...)
parts = append(parts, kb.Key)
return strings.Join(parts, "+")
}