mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-08 12:13:31 -04:00
feat(mango): first-class MangoWM support across DMS, dankinstaller & UI tools
- Bring up Mango to parity with niri/hyprland via a native JSON-IPC w/Native MangoServic., replaces the legacy dwl/`mmsg` path and recent breaking changes - Dankinstall: mango supported installer, config/binds templates, and packaging (Arch AUR, Fedora Terra auto-enable, Gentoo GURU) - Window rules: Go provider + CLI + Settings GUI editor - Keybinds + config reload on edit (mmsg dispatch reload_config) - Misc new supported options in DMS settings
This commit is contained in:
@@ -397,6 +397,14 @@ func (m *MangoWCProvider) writeBindLine(sb *strings.Builder, bind *mangowcOverri
|
||||
mods, key := m.parseKeyString(bind.Key)
|
||||
command, params := m.parseAction(bind.Action)
|
||||
|
||||
// Description goes on the line ABOVE the bind: mango doesn't strip inline `#`
|
||||
// comments from a value, so a trailing comment would break spawn (extra argv).
|
||||
if bind.Description != "" {
|
||||
sb.WriteString("# ")
|
||||
sb.WriteString(bind.Description)
|
||||
sb.WriteString("\n")
|
||||
}
|
||||
|
||||
sb.WriteString("bind=")
|
||||
if mods == "" {
|
||||
sb.WriteString("none")
|
||||
@@ -413,11 +421,6 @@ func (m *MangoWCProvider) writeBindLine(sb *strings.Builder, bind *mangowcOverri
|
||||
sb.WriteString(params)
|
||||
}
|
||||
|
||||
if bind.Description != "" {
|
||||
sb.WriteString(" # ")
|
||||
sb.WriteString(bind.Description)
|
||||
}
|
||||
|
||||
sb.WriteString("\n")
|
||||
}
|
||||
|
||||
|
||||
@@ -216,101 +216,37 @@ func mangowcAutogenerateComment(command, params string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *MangoWCParser) getKeybindAtLine(lineNumber int) *MangoWCKeyBinding {
|
||||
func (p *MangoWCParser) getKeybindAtLine(lineNumber int, precedingComment string) *MangoWCKeyBinding {
|
||||
if lineNumber >= len(p.contentLines) {
|
||||
return nil
|
||||
}
|
||||
|
||||
line := p.contentLines[lineNumber]
|
||||
|
||||
bindMatch := regexp.MustCompile(`^(bind[lsr]*)\s*=\s*(.+)$`)
|
||||
matches := bindMatch.FindStringSubmatch(line)
|
||||
if len(matches) < 3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
bindType := matches[1]
|
||||
content := matches[2]
|
||||
|
||||
parts := strings.SplitN(content, "#", 2)
|
||||
keys := parts[0]
|
||||
|
||||
var comment string
|
||||
if len(parts) > 1 {
|
||||
comment = strings.TrimSpace(parts[1])
|
||||
}
|
||||
|
||||
if strings.HasPrefix(comment, MangoWCHideComment) {
|
||||
return nil
|
||||
}
|
||||
|
||||
keyFields := strings.SplitN(keys, ",", 4)
|
||||
if len(keyFields) < 3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
mods := strings.TrimSpace(keyFields[0])
|
||||
key := strings.TrimSpace(keyFields[1])
|
||||
command := strings.TrimSpace(keyFields[2])
|
||||
|
||||
var params string
|
||||
if len(keyFields) > 3 {
|
||||
params = strings.TrimSpace(keyFields[3])
|
||||
}
|
||||
|
||||
if comment == "" {
|
||||
comment = mangowcAutogenerateComment(command, params)
|
||||
}
|
||||
|
||||
var modList []string
|
||||
if mods != "" && !strings.EqualFold(mods, "none") {
|
||||
modstring := mods + string(MangoWCModSeparators[0])
|
||||
p := 0
|
||||
for index, char := range modstring {
|
||||
isModSep := false
|
||||
for _, sep := range MangoWCModSeparators {
|
||||
if char == sep {
|
||||
isModSep = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isModSep {
|
||||
if index-p > 1 {
|
||||
modList = append(modList, modstring[p:index])
|
||||
}
|
||||
p = index + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ = bindType
|
||||
|
||||
return &MangoWCKeyBinding{
|
||||
Mods: modList,
|
||||
Key: key,
|
||||
Command: command,
|
||||
Params: params,
|
||||
Comment: comment,
|
||||
}
|
||||
return p.getKeybindAtLineContent(p.contentLines[lineNumber], precedingComment)
|
||||
}
|
||||
|
||||
func (p *MangoWCParser) ParseKeys() []MangoWCKeyBinding {
|
||||
var keybinds []MangoWCKeyBinding
|
||||
var pendingComment string
|
||||
|
||||
for lineNumber := 0; lineNumber < len(p.contentLines); lineNumber++ {
|
||||
line := p.contentLines[lineNumber]
|
||||
if line == "" || strings.HasPrefix(strings.TrimSpace(line), "#") {
|
||||
trimmed := strings.TrimSpace(p.contentLines[lineNumber])
|
||||
if trimmed == "" {
|
||||
pendingComment = ""
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(trimmed, "#") {
|
||||
pendingComment = strings.TrimSpace(strings.TrimPrefix(trimmed, "#"))
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(trimmed, "bind") {
|
||||
pendingComment = ""
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(strings.TrimSpace(line), "bind") {
|
||||
continue
|
||||
}
|
||||
|
||||
keybind := p.getKeybindAtLine(lineNumber)
|
||||
keybind := p.getKeybindAtLine(lineNumber, pendingComment)
|
||||
if keybind != nil {
|
||||
keybinds = append(keybinds, *keybind)
|
||||
}
|
||||
pendingComment = ""
|
||||
}
|
||||
|
||||
return keybinds
|
||||
@@ -459,21 +395,35 @@ func (p *MangoWCParser) parseFileWithSource(filePath string) ([]MangoWCKeyBindin
|
||||
p.currentSource = absPath
|
||||
|
||||
var keybinds []MangoWCKeyBinding
|
||||
var pendingComment string
|
||||
lines := strings.Split(string(data), "\n")
|
||||
|
||||
for lineNum, line := range lines {
|
||||
for _, line := range lines {
|
||||
trimmed := strings.TrimSpace(line)
|
||||
|
||||
if trimmed == "" {
|
||||
pendingComment = ""
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(trimmed, "source") {
|
||||
p.handleSource(trimmed, filepath.Dir(absPath), &keybinds)
|
||||
pendingComment = ""
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(trimmed, "#") {
|
||||
pendingComment = strings.TrimSpace(strings.TrimPrefix(trimmed, "#"))
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(trimmed, "bind") {
|
||||
pendingComment = ""
|
||||
continue
|
||||
}
|
||||
|
||||
kb := p.getKeybindAtLineContent(line, lineNum)
|
||||
kb := p.getKeybindAtLineContent(line, pendingComment)
|
||||
pendingComment = ""
|
||||
if kb == nil {
|
||||
continue
|
||||
}
|
||||
@@ -529,7 +479,10 @@ func (p *MangoWCParser) parseDMSBindsDirectly(dmsBindsPath string) []MangoWCKeyB
|
||||
return keybinds
|
||||
}
|
||||
|
||||
func (p *MangoWCParser) getKeybindAtLineContent(line string, _ int) *MangoWCKeyBinding {
|
||||
// getKeybindAtLineContent parses one `bind=` line. precedingComment (a `# ...`
|
||||
// line directly above) is the description: mango feeds inline comments to spawn
|
||||
// as argv, so DMS keeps descriptions on the line above; inline `#` is a fallback.
|
||||
func (p *MangoWCParser) getKeybindAtLineContent(line string, precedingComment string) *MangoWCKeyBinding {
|
||||
bindMatch := regexp.MustCompile(`^(bind[lsr]*)\s*=\s*(.+)$`)
|
||||
matches := bindMatch.FindStringSubmatch(line)
|
||||
if len(matches) < 3 {
|
||||
@@ -544,6 +497,9 @@ func (p *MangoWCParser) getKeybindAtLineContent(line string, _ int) *MangoWCKeyB
|
||||
if len(parts) > 1 {
|
||||
comment = strings.TrimSpace(parts[1])
|
||||
}
|
||||
if comment == "" {
|
||||
comment = strings.TrimSpace(precedingComment)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(comment, MangoWCHideComment) {
|
||||
return nil
|
||||
|
||||
@@ -174,7 +174,7 @@ func TestMangoWCGetKeybindAtLine(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
parser := NewMangoWCParser("")
|
||||
parser.contentLines = []string{tt.line}
|
||||
result := parser.getKeybindAtLine(0)
|
||||
result := parser.getKeybindAtLine(0, "")
|
||||
|
||||
if tt.expected == nil {
|
||||
if result != nil {
|
||||
@@ -421,7 +421,7 @@ func TestMangoWCInvalidBindLines(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
parser := NewMangoWCParser("")
|
||||
parser.contentLines = []string{tt.line}
|
||||
result := parser.getKeybindAtLine(0)
|
||||
result := parser.getKeybindAtLine(0, "")
|
||||
|
||||
if result != nil {
|
||||
t.Errorf("expected nil for invalid line, got %+v", result)
|
||||
|
||||
Reference in New Issue
Block a user