#!/usr/bin/env bash

set -euo pipefail

file="${1:-$HOME/.config/hypr/conf/keybinds.lua}"

awk '
function trim(s) {
    sub(/^[[:space:]]+/, "", s)
    sub(/[[:space:]]+$/, "", s)
    return s
}

function escape_markup(s) {
    gsub(/&/, "\\&amp;", s)
    gsub(/</, "\\&lt;", s)
    gsub(/>/, "\\&gt;", s)
    return s
}

function print_group_header(name) {
    if (printed_any_group) {
        print ""
    }

    pretty_group = escape_markup(name)
    printf "<span foreground=\"#f9e2af\"><b>%s</b></span>\n", pretty_group
    printed_any_group = 1
}

function parse_first_arg(s,    depth, in_string, out, i, c, prev) {
    depth = 0
    in_string = 0
    out = ""

    for (i = 1; i <= length(s); i++) {
        c = substr(s, i, 1)
        prev = (i > 1 ? substr(s, i - 1, 1) : "")

        if (c == "\"" && prev != "\\") {
            in_string = !in_string
        }

        if (!in_string) {
            if (c == "(") depth++
            else if (c == ")") depth--
            else if (c == "," && depth == 0) break
        }

        out = out c
    }

    return trim(out)
}

BEGIN {
    in_keybinds = 0
    group = ""
    last_group = ""
    mainMod = "mainMod"
    printed_any_group = 0
}

{
    line = $0

    if (match(line, /^[[:space:]]*local[[:space:]]+mainMod[[:space:]]*=[[:space:]]*"[^"]+"/)) {
        tmp = line
        sub(/^[^"]*"/, "", tmp)
        sub(/".*$/, "", tmp)
        mainMod = tmp
    }

    if (line ~ /^[[:space:]]*--[[:space:]]*KeyBinds[[:space:]]*$/) {
        in_keybinds = 1
        next
    }

    if (!in_keybinds)
        next

    if (line ~ /^[[:space:]]*--[[:space:]]*[^-].*$/) {
        group = line
        sub(/^[[:space:]]*--[[:space:]]*/, "", group)
        group = trim(group)
        next
    }

    if (line ~ /hl\.bind[[:space:]]*\(/ && line ~ /--/) {
        if (group != last_group) {
            print_group_header(group)
            last_group = group
        }

        desc = line
        sub(/^.*--[[:space:]]*/, "", desc)
        desc = trim(desc)

        bind = line
        sub(/^[[:space:]]*hl\.bind[[:space:]]*\(/, "", bind)

        key = parse_first_arg(bind)

        gsub(/[[:space:]]*\.\.[[:space:]]*/, "", key)
        gsub(/"/, "", key)
        gsub(/mainMod/, mainMod, key)
        key = trim(key)

        pretty_key  = escape_markup(key)
        pretty_desc = escape_markup(desc)

        printf "  <span foreground=\"#cba6f7\">%s</span>  <span foreground=\"#a6adc8\">— %s</span>\n", pretty_key, pretty_desc
    }
}
' "$file" | rofi -dmenu -markup-rows -i -p "Keybinds" >/dev/null
