#!/usr/bin/perl use strict; use JSONConnection; use JSON::Syck; use POSIX qw(strftime); use CursesChatMainwindow; our $CFG; our %known_ids; our $js; our %completion = map { $_ => 1 } qw{ /buffer /list_buffers /colors }; my $d = 0; my $wt; sub timer { $wt = AnyEvent->timer (after => 3, cb => sub { printline (status => [0, "TEST $d"]); $d++; timer (); }); } sub write_chatline { my ($buffer, $nick, $time, $msg) = @_; my $ts = POSIX::strftime ("%T", localtime ($time)); $ts = "[$ts] $nick> "; my (@chatline) = (("p".length $ts), 0, "$ts$msg"); printline ($buffer, \@chatline); } sub load_cfg { $CFG ||= {}; return unless -e "$ENV{HOME}/.jsonircclrc"; open CFGH, "<", "$ENV{HOME}/.jsonircclrc" or die "Couldn't open ~/.jsonircclrc: $!"; $::CFG = JSON::Syck::Load (do { local $/; }); } load_cfg (); my $c = AnyEvent->condvar; #timer (); $js = JSONClientConnection->new (packet_cb => sub { my ($js, $data) = @_; require JSON::Syck; if ($data->{type} eq 'message') { my ($src_id) = ($data->{src}); $known_ids{$src_id}->{send_id} = $data->{to}->{id}; write_chatline ($src_id, $data->{from}->{id}, $data->{timestamp}, $data->{message}); } printline (debug => [0, JSON::Syck::Dump ($data)]); }); $js->connect (localhost => 1236); CursesChatMainwindow::init; printline (status => ['p0', 0, "Connected!"]); printline (statusline => [20, "Welcome to the json enhanced chat framework!"]); sub find_common_prefix { my (@words) = @_; @words = sort { length ($a) <=> length ($b) } @words; my $shortest = $words[0]; while ($shortest ne '') { my $no_match = 0; for (@words) { unless (/^\Q$shortest\E/) { $no_match = 1; last; } } return $shortest if not $no_match; substr $shortest, -1, 1, ''; } return ''; } CursesChatMainwindow::register_complete_cb (sub { my ($word, $first_compl, $idx, @line) = @_; # TODO: make completion cycling with $first_compl # printline (undef, [0, "f[$first_compl]"]); my @found; if ($idx == 0) { for (keys %completion) { if (/^\Q$word\E/) { push @found, $_; } } } else { my %buffers = map { $_ => 1 } list_buffers; for (keys %known_ids) { delete $buffers{$_}; if (/^\Q$word\E/) { push @found, $_; } } for (keys %buffers) { if (/^\Q$word\E/) { push @found, $_; } } } return "$found[0] " if @found == 1; if (@found) { printline (undef, [0, "$word: " . join ", ", @found]); return find_common_prefix (@found); } return $word; }); CursesChatMainwindow::register_input_cb (sub { my ($input, $escape) = @_; unless (defined $input) { if (exists $CFG->{buffers}->{$escape}) { select_buffer (my $buf = $CFG->{buffers}->{$escape} || 'status'); printline (statusline => [20, "[$buf]"]); } else { select_buffer ('status'); printline (statusline => [20, "[status]"]); } return; } if ($input =~ m/^\/buffer\s*(\S+)/) { select_buffer ("$1"); printline (statusline => [20, "[$1]"]); } elsif ($input =~ m/^\/list_buffers/) { printline (undef, [0, "buffers:"]); for (list_buffers) { printline (undef, [0, "- $_"]); } } elsif ($input =~ m/^\/colors/) { CursesChatMainwindow::print_colors; } else { my $dest_id = "" . current_buffer (); my $msg = { type => 'message', dest => $dest_id, message => $input }; $js->send_data ($msg); printline (debug => [0, JSON::Syck::Dump ($msg)]); write_chatline ($dest_id, $known_ids{$dest_id}->{send_id} || "", time, $input); } }); $c->wait; CursesChatMainwindow::end;