mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-11 07:58:30 -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
|
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 {
|
func NewNiriProvider(configDir string) *NiriProvider {
|
||||||
if configDir == "" {
|
if configDir == "" {
|
||||||
configDir = defaultNiriConfigDir()
|
configDir = defaultNiriConfigDir()
|
||||||
@@ -353,7 +367,7 @@ func (n *NiriProvider) buildActionFromNode(bindNode *document.Node) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if actionNode.Properties != nil {
|
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 {
|
if val, ok := actionNode.Properties.Get(propName); ok {
|
||||||
parts = append(parts, propName+"="+val.String())
|
parts = append(parts, propName+"="+val.String())
|
||||||
}
|
}
|
||||||
@@ -441,10 +455,10 @@ func (n *NiriProvider) buildActionNode(action string) *document.Node {
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
node.SetName(parts[0])
|
node.SetName(parts[0].value)
|
||||||
for _, arg := range parts[1:] {
|
for _, arg := range parts[1:] {
|
||||||
if strings.Contains(arg, "=") {
|
if n.isNiriActionPropertyToken(arg) {
|
||||||
kv := strings.SplitN(arg, "=", 2)
|
kv := strings.SplitN(arg.value, "=", 2)
|
||||||
switch kv[1] {
|
switch kv[1] {
|
||||||
case "true":
|
case "true":
|
||||||
node.AddProperty(kv[0], true, "")
|
node.AddProperty(kv[0], true, "")
|
||||||
@@ -455,13 +469,25 @@ func (n *NiriProvider) buildActionNode(action string) *document.Node {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node.AddArgument(arg, "")
|
node.AddArgument(arg.value, "")
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NiriProvider) parseActionParts(action string) []string {
|
func (n *NiriProvider) isNiriActionPropertyToken(part niriActionPart) bool {
|
||||||
var parts []string
|
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 current strings.Builder
|
||||||
var inQuote, escaped, wasQuoted bool
|
var inQuote, escaped, wasQuoted bool
|
||||||
|
|
||||||
@@ -477,7 +503,7 @@ func (n *NiriProvider) parseActionParts(action string) []string {
|
|||||||
inQuote = !inQuote
|
inQuote = !inQuote
|
||||||
case r == ' ' && !inQuote:
|
case r == ' ' && !inQuote:
|
||||||
if current.Len() > 0 || wasQuoted {
|
if current.Len() > 0 || wasQuoted {
|
||||||
parts = append(parts, current.String())
|
parts = append(parts, niriActionPart{value: current.String(), quoted: wasQuoted})
|
||||||
current.Reset()
|
current.Reset()
|
||||||
wasQuoted = false
|
wasQuoted = false
|
||||||
}
|
}
|
||||||
@@ -486,7 +512,7 @@ func (n *NiriProvider) parseActionParts(action string) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if current.Len() > 0 || wasQuoted {
|
if current.Len() > 0 || wasQuoted {
|
||||||
parts = append(parts, current.String())
|
parts = append(parts, niriActionPart{value: current.String(), quoted: wasQuoted})
|
||||||
}
|
}
|
||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,6 +234,58 @@ func TestNiriGenerateBindsContent(t *testing.T) {
|
|||||||
expected: `binds {
|
expected: `binds {
|
||||||
Mod+Space hotkey-overlay-title="Application Launcher" { spawn "dms" "ipc" "call" "spotlight" "toggle"; }
|
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