File Coverage

blib/lib/App/VTide/Command/Start.pm
Criterion Covered Total %
statement 27 99 27.2
branch 0 46 0.0
condition 0 24 0.0
subroutine 9 15 60.0
pod 6 6 100.0
total 42 190 22.1


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