<commit_before>package AnyEvent::I3;
# vim:ts=4:sw=4:expandtab

use strict;
use warnings;
use JSON::XS;
use AnyEvent::Handle;
use AnyEvent::Socket;
use AnyEvent;
use Encode;

=head1 NAME

AnyEvent::I3 - communicate with the i3 window manager

=cut

our $VERSION = '0.01';

=head1 VERSION

Version 0.01

=head1 SYNOPSIS

This module connects to the i3 window manager using the UNIX socket based
IPC interface it provides (if enabled in the configuration file). You can
then subscribe to events or send messages and receive their replies.

Note that as soon as you subscribe to some kind of event, you should B<NOT>
send any more messages as race conditions might occur. Instead, open another
connection for that.

    use AnyEvent::I3 qw(:all);

    my $i3 = i3("/tmp/i3-ipc.sock");

    $i3->connect->recv;
    say "Connected to i3";

    my $workspaces = $i3->message(TYPE_GET_WORKSPACES)->recv;
    say "Currently, you use " . @{$workspaces} . " workspaces";

=head1 EXPORT

=head2 $i3 = i3([ $path ]);

Creates a new C<AnyEvent::I3> object and returns it. C<path> is the path of
the UNIX socket to connect to.

=head1 SUBROUTINES/METHODS

=cut

use Exporter qw(import);
use base 'Exporter';

our @EXPORT = qw(i3);

use constant TYPE_COMMAND => 0;
use constant TYPE_GET_WORKSPACES => 1;
use constant TYPE_SUBSCRIBE => 2;
use constant TYPE_GET_OUTPUTS => 3;

our %EXPORT_TAGS = ( 'all' => [
    qw(i3 TYPE_COMMAND TYPE_GET_WORKSPACES TYPE_SUBSCRIBE TYPE_GET_OUTPUTS)
] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );

my $magic = "i3-ipc";

# TODO: auto-generate this from the header file? (i3/ipc.h)
my $event_mask = (1 << 31);
my %events = (
    workspace => ($event_mask | 0),
    output => ($event_mask | 1),
);

sub i3 {
    AnyEvent::I3->new(@_)
}

=head2 $i3 = AnyEvent::I3->new([ $path ])

Creates a new C<AnyEvent::I3> object and returns it. C<path> is the path of
the UNIX socket to connect to.

=cut
sub new {
    my ($class, $path) = @_;

    $path ||= '/tmp/i3-ipc.sock';

    bless { path => $path } => $class;
}

=head2 $i3->connect

Establishes the connection to i3. Returns an C<AnyEvent::CondVar> which will
be triggered with a boolean (true if the connection was established) as soon as
the connection has been established.

    if ($i3->connect->recv) {
        say "Connected to i3";
    }

=cut
sub connect {
    my ($self) = @_;
    my $hdl;
    my $cv = AnyEvent->condvar;

    tcp_connect "unix/", $self->{path}, sub {
        my ($fh) = @_;

        return $cv->send(0) unless $fh;

        $self->{ipchdl} = AnyEvent::Handle->new(
            fh => $fh,<commit_msg>kill left-over variable<commit_after>package AnyEvent::I3;
# vim:ts=4:sw=4:expandtab

use strict;
use warnings;
use JSON::XS;
use AnyEvent::Handle;
use AnyEvent::Socket;
use AnyEvent;
use Encode;

=head1 NAME

AnyEvent::I3 - communicate with the i3 window manager

=cut

our $VERSION = '0.01';

=head1 VERSION

Version 0.01

=head1 SYNOPSIS

This module connects to the i3 window manager using the UNIX socket based
IPC interface it provides (if enabled in the configuration file). You can
then subscribe to events or send messages and receive their replies.

Note that as soon as you subscribe to some kind of event, you should B<NOT>
send any more messages as race conditions might occur. Instead, open another
connection for that.

    use AnyEvent::I3 qw(:all);

    my $i3 = i3("/tmp/i3-ipc.sock");

    $i3->connect->recv;
    say "Connected to i3";

    my $workspaces = $i3->message(TYPE_GET_WORKSPACES)->recv;
    say "Currently, you use " . @{$workspaces} . " workspaces";

=head1 EXPORT

=head2 $i3 = i3([ $path ]);

Creates a new C<AnyEvent::I3> object and returns it. C<path> is the path of
the UNIX socket to connect to.

=head1 SUBROUTINES/METHODS

=cut

use Exporter qw(import);
use base 'Exporter';

our @EXPORT = qw(i3);

use constant TYPE_COMMAND => 0;
use constant TYPE_GET_WORKSPACES => 1;
use constant TYPE_SUBSCRIBE => 2;
use constant TYPE_GET_OUTPUTS => 3;

our %EXPORT_TAGS = ( 'all' => [
    qw(i3 TYPE_COMMAND TYPE_GET_WORKSPACES TYPE_SUBSCRIBE TYPE_GET_OUTPUTS)
] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );

my $magic = "i3-ipc";

# TODO: auto-generate this from the header file? (i3/ipc.h)
my $event_mask = (1 << 31);
my %events = (
    workspace => ($event_mask | 0),
    output => ($event_mask | 1),
);

sub i3 {
    AnyEvent::I3->new(@_)
}

=head2 $i3 = AnyEvent::I3->new([ $path ])

Creates a new C<AnyEvent::I3> object and returns it. C<path> is the path of
the UNIX socket to connect to.

=cut
sub new {
    my ($class, $path) = @_;

    $path ||= '/tmp/i3-ipc.sock';

    bless { path => $path } => $class;
}

=head2 $i3->connect

Establishes the connection to i3. Returns an C<AnyEvent::CondVar> which will
be triggered with a boolean (true if the connection was established) as soon as
the connection has been established.

    if ($i3->connect->recv) {
        say "Connected to i3";
    }

=cut
sub connect {
    my ($self) = @_;
    my $cv = AnyEvent->condvar;

    tcp_connect "unix/", $self->{path}, sub {
        my ($fh) = @_;

        return $cv->send(0) unless $fh;

        $self->{ipchdl} = AnyEvent::Handle->new(
            fh => $fh,
{'fraction_non_alphanumeric': 0.13211186113789777, 'fraction_numerical': 0.020829315332690453, 'mean_word_length': 3.549122807017544, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3781990', 'n_tokens_mistral': 1928, 'n_tokens_neox': 1859, 'n_words': 615}