#!/usr/bin/env fish

# A menu for selecting audio devices using PulseAudio. Supports both outputs and inputs.

function get_display_name
    set -l name $argv[1]
    set -l list $argv[2]

    set -l desc (pactl list $list | grep -A 2 "Name: $name" | grep 'Description:' | string split ':' --fields 2 | string trim)
    if test -z "$desc"
        echo "$name"
    else
        echo "$desc"
    end
end

function get_sink_display_name
    get_display_name $argv[1] sinks
end

function get_source_display_name
    get_display_name $argv[1] sources
end

function list_devices
    set -l default_sink (pactl get-default-sink)
    set -l default_sink_display_name (get_sink_display_name "$default_sink")

    set -l default_source (pactl get-default-source)
    set -l default_source_display_name (get_source_display_name "$default_source")

    set -l options "󰓃 $(get_sink_display_name $default_sink)\n󰍬 $(get_source_display_name $default_source)"
    set selected (echo -e "$options" | fuzzel -d -p "audio>" -w 40 --minimal-lines --index)
    switch $selected
        case 0
            select_sink
        case 1
            select_source
    end
end

function select_sink
    set -l sinks (pactl list sinks | rg "Name:" | cut -d' ' -f2-)
    set -l options (
        for sink in $sinks
            echo "$sink\t$(get_sink_display_name $sink)"
        end | sort | string join "\n"
    )
    set -l selected (echo -e "$options" | fuzzel -d --with-nth 2 -p "select output>" -w 40 --minimal-lines)
    if test -z "$selected"
        return
    end
    pactl set-default-sink (string split \t $selected)[1]; or notify-send "Failed to set default output to '$selected'" && return
    notify-send "Default output set to '$selected'"
end

function select_source
    set -l sources (pactl list sources | rg "Name:" | cut -d' ' -f2-)
    set -l options (
        for source in $sources
            echo "$source\t$(get_source_display_name $source)"
        end | sort | string join "\n"
    )
    set -l selected (echo -e "$options" | fuzzel -d --with-nth 2 -p "select input>" -w 40 --minimal-lines)
    if test -z "$selected"
        return
    end
    pactl set-default-source (string split \t $selected)[1]; or notify-send "Failed to set default input to '$selected'" && return
    notify-send "Default input set to '$selected'"
end

list_devices
