File Coverage

blib/lib/App/VTide/Command/Start.pm
Criterion Covered Total %
statement 27 98 27.5
branch 0 46 0.0
condition 0 24 0.0
subroutine 9 15 60.0
pod 6 6 100.0
total 42 189 22.2


line stmt bran cond sub pod time code
1             package App::VTide::Command::Start;
2              
3             # Created on: 2016-01-30 15:06:48
4             # Create by: Ivan Wills
5             # $Id$
6             # $Revision$, $HeadURL$, $Date$
7             # $Revision$, $Source$, $Date$
8              
9 1     1   555 use Moo;
  1         3  
  1         5  
10 1     1   2378 use warnings;
  1         2  
  1         26  
11 1     1   4 use version;
  1         2  
  1         5  
12 1     1   59 use Carp;
  1         3  
  1         47  
13 1     1   6 use English qw/ -no_match_vars /;
  1         2  
  1         4  
14 1     1   349 use File::chdir;
  1         3  
  1         80  
15 1     1   8 use Path::Tiny;
  1         2  
  1         36  
16 1     1   5 use YAML::Syck;
  1         2  
  1         48  
17 1     1   6 use App::VTide::Sessions;
  1         2  
  1         1368  
18              
19             extends 'App::VTide::Command';
20              
21             our $VERSION = version->new('1.0.2');
22             our $NAME = 'start';
23             our $OPTIONS =
24             [ 'windows|w=i', 'add|add-to-session|a', 'test|T!', 'verbose|v+', ];
25 0     0 1   sub details_sub { return ( $NAME, $OPTIONS ) }
26              
27             has sessions => (
28             is => 'ro',
29             lazy => 1,
30             default => sub {
31             App::VTide::Sessions->new(
32             sessions_file => path $ENV{HOME},
33             '.vtide/sessions.yml'
34             );
35             },
36             );
37              
38             sub run {
39 0     0 1   my ($self) = @_;
40              
41 0           my ( $name, $dir ) = $self->session_dir( $self->options->files->[0] );
42              
43 0           local $CWD = $dir;
44              
45 0           $self->save_session( $name, $dir );
46              
47 0           $self->hooks->run( 'start_pre', $name, $dir );
48              
49 0           $self->ctags();
50              
51 0 0         if ( $self->options->default->{add} ) {
52 0           $self->sessions->add_session($name);
53             }
54              
55 0   0       return $self->tmux( $self->vtide->config->data->{title} || $name, $name );
56             }
57              
58             sub ctags {
59 0     0 1   my ($self) = @_;
60 0           my $ctags = path( '/usr', 'bin', 'ctags' );
61              
62 0 0 0       return if !$self->config->get->{start}{ctags} || !-x $ctags;
63              
64 0           my @cmd = ( $ctags, $self->config->get->{start}{ctags} );
65              
66 0           for my $exclude ( @{ $self->config->get->{start}{"ctags-exclude"} } ) {
  0            
67 0 0         if ( $self->config->get->{start}{"ctags-excludes"}{$exclude} ) {
68             push @cmd,
69 0           map { "--exclude=$_" }
70 0           @{ $self->config->get->{start}{"ctags-excludes"}{$exclude} };
  0            
71             }
72             else {
73 0           push @cmd, "--exclude=$exclude";
74             }
75             }
76              
77 0           system @cmd;
78             }
79              
80             sub tmux {
81 0     0 1   my ( $self, $title, $name ) = @_;
82              
83 0 0         eval { require Term::Title; }
  0            
84             and Term::Title::set_titlebar($title);
85              
86 0           my %session = map { /(^[^:]+)/xms; $1 => 1 } `tmux ls`;
  0            
  0            
87 0 0         if ( $session{$name} ) {
88              
89             # reconnect
90 0           exec 'tmux', 'attach-session', '-t', $name;
91             }
92              
93 0 0         my $v = $self->defaults->{verbose} ? '--verbose' : '';
94 0           $v .= " --name $name";
95 0           my $tmux = 'tmux -u2 ';
96 0   0       my $count = $self->defaults->{windows} || $self->config->get->{count};
97              
98 0           for my $window ( 1 .. $count ) {
99 0           $tmux .= $self->tmux_window( $window, "vtide run $v", $name );
100             }
101 0           $tmux .= "select-window -t 1";
102              
103 0 0         if ( $self->defaults->{test} ) {
104 0           print "$tmux\n";
105 0           return 1;
106             }
107              
108 0 0         mkdir '.vtide' if !-d '.vtide';
109 0           my $fh = path( '.vtide', 'start.log' )->opena;
110 0           print {$fh} '[' . localtime . "] START TMUX $tmux\n";
  0            
111              
112 0           system $tmux;
113              
114 0           print {$fh} '[' . localtime . "] END TMUX $tmux\n";
  0            
115             }
116              
117             sub tmux_window {
118 0     0 1   my ( $self, $term, $cmd, $name, $split ) = @_;
119 0 0         my $conf = !$term ? {} : $self->config->get->{terminals}{$term};
120 0 0         my $out =
    0          
121             $split ? ''
122             : $term == 1 ? "new-session -s $name '$cmd $term' \\; "
123             : "new-window '$cmd $term' \\; ";
124 0 0         my $letter = !$term ? '' : 'a';
125              
126 0 0 0       if ( !$conf || ref $conf ne 'HASH' ) {
127 0           $conf = {};
128             }
129              
130 0   0       $term ||= '';
131 0   0       $split ||= $conf->{split};
132              
133 0   0       for my $split ( split //xms, ( $split || '' ) ) {
134 0 0 0       next if !defined $split || $split eq '';
135              
136 0 0         my $arg =
    0          
    0          
    0          
    0          
137             $split eq 'H' ? 'split-window -h'
138             : $split eq 'h' ? 'split-window -dh'
139             : $split eq 'V' ? 'split-window -v'
140             : $split eq 'v' ? 'split-window -dv'
141             : $split =~ /^\d$/x ? 'select-pane -t ' . $split
142             : die "Unknown split for terminal $term $split (split = '$split')!\n";
143              
144 0 0         $out .=
145             $split =~ /^\d$/xms ? "$arg \\; " : "$arg '$cmd $term$letter' \\; ";
146 0 0         $letter++ if $letter;
147             }
148              
149 0 0         if ( $conf->{tmux} ) {
150 0           $out .= "$conf->{tmux} \\; ";
151             }
152              
153 0           return $out;
154             }
155              
156             sub auto_complete {
157 0     0 1   my ($self) = @_;
158              
159 0           my $file = $self->history;
160 0   0       my $sessions = eval { LoadFile($file) } || {};
161              
162 0           my $env = $self->options->files->[-1];
163 0 0         print join ' ', grep { $env ne 'start' ? /^$env/xms : 1 }
164 0           sort keys %{ $sessions->{sessions} };
  0            
165              
166 0           return;
167             }
168              
169             1;
170              
171             __END__
172              
173             =head1 NAME
174              
175             App::VTide::Command::Start - Start a session
176              
177             =head1 VERSION
178              
179             This documentation refers to App::VTide::Command::Start version 1.0.2
180              
181             =head1 SYNOPSIS
182              
183             vtide start
184             vtide start name [[-w|--window] num]
185             vtide start [--help|--man]
186              
187             OPTIONS:
188             name
189             The project to start (If not specified the current
190             directory is used to find a .vtide.yml file to start)
191              
192             -w --windows[=]int
193             Use a different number of windows from the configured
194             number (i.e. as set is .vtide.yml)
195             -T --test Test a config (show the tmux command)
196             -v --verbose Show more details out put (passed on to run as well)
197             --help Show this help
198             --man Show full documentation
199              
200             =head1 DESCRIPTION
201              
202             Starts up an existing VTide project, either by name for by using the
203             configuration in the current directory.
204              
205             =head1 SUBROUTINES/METHODS
206              
207             =head2 C<run ()>
208              
209             Starts the tmux session running a C<vtide run> command in each terminal
210              
211             =head2 C<ctags ()>
212              
213             Runs the ctags command if the config option I<ctags> in the I<start> group is set
214              
215             =head2 C<tmux ( $name )>
216              
217             Run a tmux session with the name C<$name>
218              
219             =head2 C<tmux_window ( $name )>
220              
221             Creates the C<tmux> configuration for a new window.
222              
223             =head2 C<auto_complete ()>
224              
225             Auto completes session names
226              
227             =head2 C<details_sub ()>
228              
229             Returns the commands details.
230              
231             =head1 HOOKS
232              
233             =head2 C<start_pre ( $name, $dir )>
234              
235             This is run just before the tmux session is started, the C<$name> and the
236             directory (C<$dir>) of the project are passed.
237              
238             =head1 DIAGNOSTICS
239              
240             =head1 CONFIGURATION AND ENVIRONMENT
241              
242             =head1 DEPENDENCIES
243              
244             =head1 INCOMPATIBILITIES
245              
246             =head1 BUGS AND LIMITATIONS
247              
248             There are no known bugs in this module.
249              
250             Please report problems to Ivan Wills (ivan.wills@gmail.com).
251              
252             Patches are welcome.
253              
254             =head1 AUTHOR
255              
256             Ivan Wills - (ivan.wills@gmail.com)
257              
258             =head1 LICENSE AND COPYRIGHT
259              
260             Copyright (c) 2016 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077).
261             All rights reserved.
262              
263             This module is free software; you can redistribute it and/or modify it under
264             the same terms as Perl itself. See L<perlartistic>. This program is
265             distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
266             without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
267             PARTICULAR PURPOSE.
268              
269             =cut