#!/bin/env -S perl
use IPC::Open2;
my $key_ind = 'index';
my $prefix = '‣ ';
my @chords;
my $base_chain = undef;
my $base_len = 0;
sub for_hknode {
my ( $node, $d ) = @_;
my $seen = 0;
for my $k (sort { ${$node}{$a}{'index'} cmp ${$node}{$b}{'index'} } keys( %{$node} ))
{
next if $k eq 'index';
if( $d == 0 && $base_len > 0){ print $prefix}
$chords[ $d ] = $k;
if ($seen and $d > 0)
{
print '';
for (my $j=0; $j < $d; $j++) {
print '('.$chords[ $j ].')';
}
print '';
print $prefix if $base_len > 0;
}
$seen = 1;
if ($k eq '') {
print " ".${$node}{''} ."\n";
} else {
printf ('(%s)', $k);
for_hknode( ${$node}{$k}, $d+1 );
}
}
}
if( $#ARGV >= 0)
{
my @base_chords = split / *; */, $ARGV[0];
$base_len = $#base_chords + 1;
$base_chain = quotemeta $ARGV[0];
}
my $path = $ENV{HOME} . "/.config/sxhkd/sxhkdrc";
open my $config, "<", $path || die "Config file not found.";
my $hktree = {};
my $hknode = undef;
my $name = undef;
my $skip = 0;
my $counter = 0;
while ( <$config> )
{
chomp;
if( /\\$/o)
{ chop; next }
if( /^#!(.*)/o)
{ $name = $1 }
if( /^[[:space:]]*(?:#|$)/)
{ next }
if( /^[^[:space:]]/)
{
if( defined $base_chain and $_ !~ qr/^${base_chain}[^\w]/o ){
$skip = 1;
next;
}
$skip = 0;
@chords = split(/ *; */);
$hknode = $hktree;
my $skip = $base_len;
for my $chord (@chords)
{
if( $skip > 0) {
--$skip;
next;
}
if (not exists ${$hknode}{ $chord }){
${$hknode}{ $chord } = {};
${$hknode}{ $chord }{'index'} = sprintf '%05i', $counter;
$counter++;
}
$hknode = ${$hknode}{ $chord };
}
next;
}
next if $skip;
if (defined $name) {
${$hknode}{''} = $name;
$name = undef;
} else {
/^[ \t]*(.*)[ \t]*$/o;
${$hknode}{''} = $1;
}
${$hknode}{''}{'index'} = sprintf '%05i', $counter;
$couter++;
}
######################
$#chords = -1;
for_hknode( $hktree, 0 );