summaryrefslogtreecommitdiffstats
path: root/scripts/theme.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/theme.pl')
-rw-r--r--scripts/theme.pl451
1 files changed, 451 insertions, 0 deletions
diff --git a/scripts/theme.pl b/scripts/theme.pl
new file mode 100644
index 0000000..7d649b7
--- /dev/null
+++ b/scripts/theme.pl
@@ -0,0 +1,451 @@
+use strict;
+use vars qw($VERSION %IRSSI);
+use POSIX;
+use File::Basename;
+use File::Fetch;
+use File::Glob ':bsd_glob';
+use Getopt::Long qw/GetOptionsFromString/;
+use Storable qw/store_fd fd_retrieve/;
+use YAML::XS;
+
+use Irssi;
+
+$VERSION = '0.04';
+%IRSSI = (
+ authors => 'bw1',
+ contact => 'bw1@aol.at',
+ name => 'theme',
+ description => 'activate, show or get theme',
+ license => 'Public Domain',
+ url => 'https://scripts.irssi.org/',
+ changed => '2020-04-12',
+ modules => 'POSIX File::Basename File::Fetch File::Glob Getopt::Long Storable YAML::XS',
+ commands=> 'theme',
+);
+
+my $help = << "END";
+%9Name%9
+ $IRSSI{name}
+%9Version%9
+ $VERSION
+%9Synopsis%9
+ /theme {-g|-get} <theme>
+ /theme [theme] [options]
+%9Options%9
+ -next|-n next theme in dir
+ -previous|-p previous theme in dir
+ -show|-s show a test text
+ -reload|-r reload the dir
+ -get|-g get a theme form a website
+ -list|-l list theme in dir
+ -update|-u download themes.yaml
+ -info|-i print info
+ -fg_color|-f set or reset the foreground color
+ -bg_color|-b set or reset the background color
+ -help|-h
+%9Description%9
+ $IRSSI{description}
+%9Settings%9
+ /set theme_source https://irssi-import.github.io/themes/
+ /set theme_local ~/.irssi/
+ /set theme_autocolor off
+%9Color%9
+ the script can set
+ VT100 text foreground color
+ VT100 text background color
+ tested with xterm, konsole, lxterm
+%9See also%9
+ https://irssi-import.github.io/themes/
+ https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+ https://en.wikipedia.org/wiki/X11_color_names
+END
+
+my (%themes, @dtl);
+my (@tl, $count);
+my ($show, $update, $get, $list, $phelp, $info, $yupdate, $fg_color, $bg_color);
+my ($noxterm);
+my %options = (
+ 'n' => sub{ $count++; $update=1},
+ 'next' => sub{ $count++; $update=1},
+ 'p' => sub{ $count--; $update=1},
+ 'previous' => sub{ $count--; $update=1},
+ 's' => \$show,
+ 'show' => \$show,
+ 'r' => \&init,
+ 'reload' => \&init,
+ 'g=s' => \$get,
+ 'get=s' => \$get,
+ 'l' => \$list,
+ 'list' => \$list,
+ 'h' => \$phelp,
+ 'help' => \$phelp,
+ 'u' => \$yupdate,
+ 'update' => \$yupdate,
+ 'i:s' => \$info,
+ 'info:s' => \$info,
+ 'f:s' => \$fg_color,
+ 'fg_color:s' => \$fg_color,
+ 'b:s' => \$bg_color,
+ 'bg_color:s' => \$bg_color,
+);
+
+my $lorem = << 'END';
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
+tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
+vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
+gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum
+dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
+invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero
+eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no
+sea takimata sanctus est Lorem ipsum dolor sit amet.
+END
+
+my ($theme_source, $theme_local, $theme_autocolor);
+my %bg_process= ();
+
+sub background {
+ my ($cmd) =@_;
+ my ($fh_r, $fh_w);
+ pipe $fh_r, $fh_w;
+ my $pid = fork();
+ if ($pid ==0 ) {
+ my @res;
+ @res= &{$cmd->{cmd}}(@{$cmd->{args}});
+ store_fd \@res, $fh_w;
+ close $fh_w;
+ POSIX::_exit(1);
+ } else {
+ $cmd->{fh_r}=$fh_r;
+ Irssi::pidwait_add($pid);
+ $bg_process{$pid}=$cmd;
+ }
+}
+
+sub sig_pidwait {
+ my ($pid, $status) = @_;
+ if (exists $bg_process{$pid}) {
+ my @res= @{ fd_retrieve($bg_process{$pid}->{fh_r})};
+ $bg_process{$pid}->{res}=[@res];
+ if (exists $bg_process{$pid}->{last}) {
+ foreach my $p (@{$bg_process{$pid}->{last}}) {
+ &$p($bg_process{$pid});
+ }
+ } else {
+ Irssi::print(join(" ",@res), MSGLEVEL_CLIENTCRAP);
+ }
+ delete $bg_process{$pid};
+ }
+}
+
+sub cmd_show {
+ my ($args, $server, $witem)=@_;
+ my $t = Irssi::settings_get_str('theme');
+ if (defined $witem) {
+ $witem->print(
+ "----- $t -- $count -----",
+ MSGLEVEL_CLIENTCRAP);
+ $witem->command('names');
+ core_printformat_module_w($witem,
+ MSGLEVEL_CLIENTCRAP, 'fe-common/core', 'pubmsg', 'testnick', $lorem, '@');
+ core_printformat_module_w($witem,
+ MSGLEVEL_CLIENTCRAP, 'fe-common/core', 'pubmsg_me', 'testnick',
+ 'me: '.substr($lorem, 0, 30),'@');
+ core_printformat_module_w($witem,
+ MSGLEVEL_CLIENTCRAP, 'fe-common/core', 'own_msg', 'me',
+ substr($lorem, 0, 30),'@');
+ } else {
+ Irssi::print(
+ "----- $t -- $count -----",
+ MSGLEVEL_CLIENTCRAP);
+ core_printformat_module(
+ MSGLEVEL_CLIENTCRAP, 'fe-common/core', 'pubmsg', 'testnick', $lorem, '@');
+ core_printformat_module(
+ MSGLEVEL_CLIENTCRAP, 'fe-common/core', 'pubmsg_me', 'testnick',
+ 'me: '.substr($lorem, 0, 30),'@');
+ core_printformat_module(
+ MSGLEVEL_CLIENTCRAP, 'fe-common/core', 'own_msg', 'me',
+ substr($lorem, 0, 30),'@');
+ }
+}
+
+sub core_printformat_module {
+ my ($level, $module, $format, @args) = @_;
+ {
+ local *CORE::GLOBAL::caller = sub { $module };
+ Irssi::printformat($level, $format, @args);
+ }
+}
+
+sub core_printformat_module_w {
+ my ($witem, $level, $module, $format, @args) = @_;
+ {
+ local *CORE::GLOBAL::caller = sub { $module };
+ $witem->printformat($level, $format, @args);
+ }
+}
+
+sub set_fg_color {
+ my ($fg) = @_;
+ if ($ENV{'TERM'} =~ m/^xterm/) {
+ if ( defined $fg ) {
+ print STDERR "\033]10;$fg\a";
+ } else {
+ print STDERR "\033]110\a";
+ }
+ } else {
+ $noxterm.=" and " if ($noxterm);
+ $noxterm.="fg_color:$fg";
+ }
+}
+
+sub set_bg_color {
+ my ($bg) = @_;
+ if ($ENV{'TERM'} =~ m/^xterm/) {
+ if ( defined $bg) {
+ print STDERR "\033]11;$bg\a";
+ } else {
+ print STDERR "\033]111\a";
+ }
+ } else {
+ $noxterm.=" and " if ($noxterm);
+ $noxterm.="bg_color:$bg";
+ }
+}
+
+
+sub get_theme {
+ my ($args)=@_;
+ local $File::Fetch::WARN=0;
+ $get.= '.theme' if $get !~ m/\.theme/;
+ my $ff= File::Fetch->new(uri => $theme_source.$get);
+ my $where = $ff->fetch( to => $theme_local ) or
+ return "Error: $theme_source$get not found";
+ return "$get downloaded.";
+}
+
+sub get_yaml {
+ local $File::Fetch::WARN=0;
+ my $get='themes.yaml';
+ if (-e $theme_local.$get) {
+ unlink $theme_local.$get;
+ }
+ my $ff= File::Fetch->new(uri => $theme_source.$get);
+ my $where = $ff->fetch( to => $theme_local ) or
+ return "Error: $theme_source$get not found";
+ return "$get downloaded.";
+}
+
+sub cmd_set {
+ my ($args, $server, $witem)=@_;
+ my $t = $tl[$count];
+ if (defined $t) {
+ Irssi::settings_set_str('theme',$t);
+ Irssi::signal_emit('setup changed');
+ if ($theme_autocolor) {
+ set_fg_color($themes{$t}->{fgColor});
+ set_bg_color($themes{$t}->{bgColor});
+ }
+ }
+}
+
+sub cmd {
+ my ($args, $server, $witem)=@_;
+ my ($ret, $arg) = GetOptionsFromString($args, %options);
+ if ( defined $$arg[0]) {
+ my $c=0;
+ foreach my $t (@tl) {
+ if ($t eq $$arg[0]) {
+ $count=$c;
+ last;
+ }
+ $c++;
+ }
+ cmd_set();
+ }
+ if (defined $update) {
+ if ($count <0) {
+ $count = $#tl+$count+1;
+ }
+ if ($count >$#tl) {
+ $count = $count-$#tl-1;
+ }
+ cmd_set();
+ $update= undef;
+ }
+ if (defined $show) {
+ cmd_show($args, $server, $witem);
+ $show = undef;
+ }
+ if (defined $get) {
+ my $cmd;
+ $cmd->{cmd}=\&get_theme;
+ $cmd->{args}=[$args];
+ $cmd->{last}=[
+ \&init,
+ \&print_result,
+ ];
+ background( $cmd );
+ $get = undef;
+ }
+ if (defined $yupdate) {
+ my $cmd;
+ $cmd->{cmd}=\&get_yaml;
+ $cmd->{last}=[
+ \&init,
+ \&print_result,
+ ];
+ background( $cmd );
+ $yupdate = undef;
+ }
+ if (defined $list) {
+ my $c=0;
+ foreach (@tl) {
+ if ($c == $count) {
+ Irssi::print(">>$_<<", MSGLEVEL_CLIENTCRAP);
+ } else {
+ Irssi::print(" $_", MSGLEVEL_CLIENTCRAP);
+ }
+ $c++;
+ }
+ $list = undef;
+ }
+ if (defined $info) {
+ cmd_info($args, $server, $witem);
+ $info = undef;
+ }
+ if (defined $phelp || $args eq '' ) {
+ cmd_help($IRSSI{name}, $server, $witem);
+ $phelp = undef;
+ }
+ if (defined $fg_color) {
+ if (length($fg_color)>0) {
+ set_fg_color($fg_color);
+ } else {
+ set_fg_color();
+ }
+ $fg_color= undef;
+ }
+ if (defined $bg_color) {
+ if (length($bg_color)>0) {
+ set_bg_color($bg_color);
+ } else {
+ set_bg_color();
+ }
+ $bg_color= undef;
+ }
+ if (defined $noxterm) {
+ Irssi::print(
+ "Do not know how to set colour for your terminal ($ENV{TERM})."
+ , MSGLEVEL_CLIENTCRAP);
+ Irssi::print(
+ "Manually configure it for $noxterm"
+ , MSGLEVEL_CLIENTCRAP);
+ $noxterm= undef;
+ }
+}
+
+sub cmd_info {
+ my ($args, $server, $witem)=@_;
+ Irssi::print("Info: $info", MSGLEVEL_CLIENTCRAP);
+ if (exists $themes{$info}) {
+ Irssi::print(Dump($themes{$info}), MSGLEVEL_CLIENTCRAP);
+ } elsif (exists $themes{$tl[$count]}) {
+ Irssi::print(Dump($themes{$tl[$count]}), MSGLEVEL_CLIENTCRAP);
+ }
+}
+
+sub cmd_help {
+ my ($args, $server, $witem)=@_;
+ $args=~ s/\s+//g;
+ if ($IRSSI{name} eq $args) {
+ Irssi::print($help, MSGLEVEL_CLIENTCRAP);
+ Irssi::signal_stop();
+ }
+}
+
+sub sig_setup_changed {
+ $theme_source= Irssi::settings_get_str($IRSSI{name}.'_source');
+ $theme_source.= '/' if $theme_source !~ m#/$#;
+ my $l= Irssi::settings_get_str($IRSSI{name}.'_local');
+ $theme_local= bsd_glob $l;
+ $theme_local.= '/' if $theme_local !~ m#/$#;
+ $theme_autocolor= Irssi::settings_get_bool($IRSSI{name}.'_autocolor');
+}
+
+sub print_result {
+ my ($cmd) = @_;
+ if (defined $cmd->{res}->[0]) {
+ Irssi::print($cmd->{res}->[0] , MSGLEVEL_CLIENTCRAP);
+ }
+}
+
+sub do_complete {
+ my ($strings, $window, $word, $linestart, $want_space) = @_;
+ return unless $linestart =~ m#^/$IRSSI{name}#;
+ return if $word =~ m#^-#;
+ if ( $linestart !~ m/(-g|-get|-i|-info)/ ) {
+ @$strings = grep { m/^$word/} @tl;
+ } else {
+ @$strings = grep { m/^$word/} @dtl;
+ }
+ Irssi::signal_stop;
+}
+
+sub init {
+ my $theme = Irssi::settings_get_str('theme');
+ my $p1= Irssi::get_irssi_dir();
+ my @t = bsd_glob $p1.'/*.theme';
+ @tl=();
+ my $c=0;
+ foreach my $fn (@t) {
+ $fn = basename($fn, '.theme');
+ push @tl, $fn;
+ $count=$c if $theme eq $fn;
+ $c++;
+ }
+ $lorem =~ s/\n/ /g;
+ if (-e $p1.'/themes.yaml') {
+ @dtl=undef;
+ my @l;
+ open my $fi, '<',$p1.'/themes.yaml';
+ my $syml= do {local $/; <$fi>};
+ close $fi;
+ eval {
+ @l = @{Load($syml)};
+ };
+ if (length($@) >0) {
+ print $@;
+ } else {
+ foreach my $e (@l) {
+ $themes{$e->{name}}=$e;
+ push @dtl, $e->{name};
+ }
+ }
+ }
+}
+
+Irssi::signal_add_first('complete word', \&do_complete);
+Irssi::signal_add('setup changed', \&sig_setup_changed);
+Irssi::signal_add('pidwait', \&sig_pidwait);
+
+Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_source', 'https://irssi-import.github.io/themes/');
+Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_local', Irssi::get_irssi_dir());
+Irssi::settings_add_bool($IRSSI{name} ,$IRSSI{name}.'_autocolor', 0);
+
+Irssi::command_bind($IRSSI{name}, \&cmd);
+my @opt=map {s/[=:].*$//, $_} keys %options;
+Irssi::command_set_options($IRSSI{name}, join(" ", @opt));
+Irssi::command_bind('help', \&cmd_help);
+
+init();
+sig_setup_changed();
+
+if (!(-e $theme_local.'themes.yaml')) {
+ my $cmd;
+ $cmd->{cmd}=\&get_yaml;
+ $cmd->{last}=[
+ \&init,
+ \&print_result,
+ ];
+ background( $cmd );
+}