mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-01 19:18:28 -04:00
fix(niri): update custom keyboard shortcut parsing properties
Fixes #2187
This commit is contained in:
@@ -19,6 +19,20 @@ type NiriProvider struct {
|
||||
parsed bool
|
||||
}
|
||||
|
||||
type niriActionPart struct {
|
||||
value string
|
||||
quoted bool
|
||||
}
|
||||
|
||||
var niriActionPropertyOrder = []string{"focus", "show-pointer", "write-to-disk", "skip-confirmation", "delay-ms"}
|
||||
var niriActionProperties = map[string]struct{}{
|
||||
"focus": {},
|
||||
"show-pointer": {},
|
||||
"write-to-disk": {},
|
||||
"skip-confirmation": {},
|
||||
"delay-ms": {},
|
||||
}
|
||||
|
||||
func NewNiriProvider(configDir string) *NiriProvider {
|
||||
if configDir == "" {
|
||||
configDir = defaultNiriConfigDir()
|
||||
@@ -353,7 +367,7 @@ func (n *NiriProvider) buildActionFromNode(bindNode *document.Node) string {
|
||||
}
|
||||
|
||||
if actionNode.Properties != nil {
|
||||
for _, propName := range []string{"focus", "show-pointer", "write-to-disk", "skip-confirmation", "delay-ms"} {
|
||||
for _, propName := range niriActionPropertyOrder {
|
||||
if val, ok := actionNode.Properties.Get(propName); ok {
|
||||
parts = append(parts, propName+"="+val.String())
|
||||
}
|
||||
@@ -441,10 +455,10 @@ func (n *NiriProvider) buildActionNode(action string) *document.Node {
|
||||
return node
|
||||
}
|
||||
|
||||
node.SetName(parts[0])
|
||||
node.SetName(parts[0].value)
|
||||
for _, arg := range parts[1:] {
|
||||
if strings.Contains(arg, "=") {
|
||||
kv := strings.SplitN(arg, "=", 2)
|
||||
if n.isNiriActionPropertyToken(arg) {
|
||||
kv := strings.SplitN(arg.value, "=", 2)
|
||||
switch kv[1] {
|
||||
case "true":
|
||||
node.AddProperty(kv[0], true, "")
|
||||
@@ -455,13 +469,25 @@ func (n *NiriProvider) buildActionNode(action string) *document.Node {
|
||||
}
|
||||
continue
|
||||
}
|
||||
node.AddArgument(arg, "")
|
||||
node.AddArgument(arg.value, "")
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func (n *NiriProvider) parseActionParts(action string) []string {
|
||||
var parts []string
|
||||
func (n *NiriProvider) isNiriActionPropertyToken(part niriActionPart) bool {
|
||||
if part.quoted || !strings.Contains(part.value, "=") {
|
||||
return false
|
||||
}
|
||||
key, _, ok := strings.Cut(part.value, "=")
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_, ok = niriActionProperties[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (n *NiriProvider) parseActionParts(action string) []niriActionPart {
|
||||
var parts []niriActionPart
|
||||
var current strings.Builder
|
||||
var inQuote, escaped, wasQuoted bool
|
||||
|
||||
@@ -477,7 +503,7 @@ func (n *NiriProvider) parseActionParts(action string) []string {
|
||||
inQuote = !inQuote
|
||||
case r == ' ' && !inQuote:
|
||||
if current.Len() > 0 || wasQuoted {
|
||||
parts = append(parts, current.String())
|
||||
parts = append(parts, niriActionPart{value: current.String(), quoted: wasQuoted})
|
||||
current.Reset()
|
||||
wasQuoted = false
|
||||
}
|
||||
@@ -486,7 +512,7 @@ func (n *NiriProvider) parseActionParts(action string) []string {
|
||||
}
|
||||
}
|
||||
if current.Len() > 0 || wasQuoted {
|
||||
parts = append(parts, current.String())
|
||||
parts = append(parts, niriActionPart{value: current.String(), quoted: wasQuoted})
|
||||
}
|
||||
return parts
|
||||
}
|
||||
|
||||
@@ -234,6 +234,58 @@ func TestNiriGenerateBindsContent(t *testing.T) {
|
||||
expected: `binds {
|
||||
Mod+Space hotkey-overlay-title="Application Launcher" { spawn "dms" "ipc" "call" "spotlight" "toggle"; }
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "spawn with equals arg",
|
||||
binds: map[string]*overrideBind{
|
||||
"Mod+B": {
|
||||
Key: "Mod+B",
|
||||
Action: `spawn /opt/browser --profile-directory=Default`,
|
||||
},
|
||||
},
|
||||
expected: `binds {
|
||||
Mod+B { spawn "/opt/browser" "--profile-directory=Default"; }
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "spawn shell command with quoted equals args",
|
||||
binds: map[string]*overrideBind{
|
||||
"Mod+C": {
|
||||
Key: "Mod+C",
|
||||
Action: `spawn sh -c "chrome --profile-directory=Default --app=x"`,
|
||||
},
|
||||
},
|
||||
expected: `binds {
|
||||
Mod+C { spawn "sh" "-c" "chrome --profile-directory=Default --app=x"; }
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "spawn env assignment stays arg",
|
||||
binds: map[string]*overrideBind{
|
||||
"Mod+E": {
|
||||
Key: "Mod+E",
|
||||
Action: `spawn env FOO=bar mycmd`,
|
||||
},
|
||||
},
|
||||
expected: `binds {
|
||||
Mod+E { spawn "env" "FOO=bar" "mycmd"; }
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "niri action property remains property",
|
||||
binds: map[string]*overrideBind{
|
||||
"Print": {
|
||||
Key: "Print",
|
||||
Action: `screenshot show-pointer=false`,
|
||||
},
|
||||
},
|
||||
expected: `binds {
|
||||
Print { screenshot show-pointer=false; }
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user