File Coverage

blib/lib/App/VTide.pm
Criterion Covered Total %
statement 35 112 31.2
branch 0 36 0.0
condition 0 7 0.0
subroutine 11 16 68.7
pod 2 2 100.0
total 48 173 27.7


line stmt bran cond sub pod time code
1             package App::VTide;
2              
3             # Created on: 2016-01-28 09:58:07
4             # Create by: Ivan Wills
5             # $Id$
6             # $Revision$, $HeadURL$, $Date$
7             # $Revision$, $Source$, $Date$
8              
9 6     6   359837 use Moo;
  6         57669  
  6         34  
10 6     6   10140 use warnings;
  6         12  
  6         192  
11 6     6   2301 use version;
  6         10028  
  6         32  
12 6     6   474 use Carp;
  6         16  
  6         349  
13 6     6   2656 use English qw/ -no_match_vars /;
  6         18549  
  6         34  
14 6     6   4971 use Getopt::Alt;
  6         3768710  
  6         45  
15 6     6   28631 use App::VTide::Config;
  6         20  
  6         209  
16 6     6   2749 use App::VTide::Hooks;
  6         38  
  6         273  
17 6     6   43 use Path::Tiny;
  6         12  
  6         285  
18 6     6   35 use YAML::Syck qw/ LoadFile DumpFile /;
  6         13  
  6         7672  
19              
20             our $VERSION = version->new('1.0.4');
21              
22             has config => (
23             is => 'rw',
24             lazy => 1,
25             default => sub { return App::VTide::Config->new() },
26             );
27             has hooks => (
28             is => 'rw',
29             lazy => 1,
30             default => sub { return App::VTide::Hooks->new( vtide => $_[0] ) },
31             );
32             has sub_commands => (
33             is => 'rw',
34             lazy => 1,
35             builder => '_sub_commands',
36             );
37              
38             sub run {
39 0     0 1 0 my ($self) = @_;
40 0         0 $self->config->history(@ARGV);
41 0         0 my @sub_commands = keys %{ $self->sub_commands };
  0         0  
42              
43             my ( $options, $cmd, $opt ) = get_options(
44             {
45             name => 'vtide-cmd',
46             conf_prefix => '.',
47             helper => 1,
48             default => { test => 0, },
49             auto_complete => sub {
50 0     0   0 my ( $option, $auto, $errors ) = @_;
51              
52             my $sub_command =
53             $option->cmd
54 0   0     0 || $ARGV[ $option->opt->{auto_complete} - 1 ]
55             || '';
56 0 0 0     0 if ( $sub_command eq '--' ) {
    0          
    0          
57 0         0 print join ' ', sort @sub_commands;
58 0         0 return;
59             }
60 0         0 elsif ( $sub_command && grep { /^$sub_command./ }
61             @sub_commands )
62             {
63 0         0 print join ' ', sort grep { /^$sub_command/ } @sub_commands;
  0         0  
64 0         0 return;
65             }
66             elsif ( !$self->sub_commands->{$sub_command} ) {
67 0         0 unshift @{ $option->files }, $sub_command;
  0         0  
68 0 0       0 $sub_command = $ENV{VTIDE_DIR} ? 'edit' : 'start';
69             }
70             eval {
71 0         0 $self->load_subcommand( $sub_command, $option )
72             ->auto_complete($auto);
73 0         0 1;
74 0 0       0 } or do {
75             print join ' ',
76 0         0 grep { /$sub_command/xms } sort @sub_commands;
  0         0  
77             }
78             },
79             auto_complete_shortener => sub {
80 0     0   0 my ( $getopt, @args ) = @_;
81 0   0     0 my $sub_command = shift @args || '';
82              
83 0 0       0 if ( grep { /^$sub_command./ } @sub_commands ) {
  0 0       0  
84 0 0       0 if ( grep { $_ eq $sub_command } @sub_commands ) {
  0         0  
85 0         0 $getopt->cmd($sub_command);
86             }
87             else {
88 0         0 unshift @args, $sub_command;
89             }
90             }
91             elsif ( !$self->sub_commands->{$sub_command} ) {
92 0 0       0 $getopt->cmd( $ENV{VTIDE_DIR} ? 'edit' : 'start' );
93 0         0 unshift @args, $sub_command;
94             }
95             else {
96 0 0       0 $getopt->cmd($sub_command) if !$getopt->cmd;
97             }
98              
99 0         0 return @args;
100             },
101             sub_command => $self->sub_commands,
102             help_package => __PACKAGE__,
103             help_packages => {
104 0         0 map { $_ => __PACKAGE__ . '::Command::' . ucfirst $_ }
  0         0  
105             @sub_commands,
106             },
107             },
108             [
109             'add|add-to-session|a',
110             'update|u!',
111             'name|n=s',
112             'test|T!',
113             'verbose|v+',
114             ],
115             );
116              
117 0 0       0 if ( !$self->sub_commands->{ $opt->cmd } ) {
118 0         0 unshift @ARGV, $opt->cmd;
119 0 0       0 $opt->cmd( $ENV{VTIDE_DIR} ? 'edit' : 'start' );
120 0         0 $opt->files( \@ARGV );
121             }
122              
123 0         0 my $subcommand = eval { $self->load_subcommand( $opt->cmd, $opt ) };
  0         0  
124 0 0       0 if ( !$subcommand ) {
125             $subcommand =
126 0 0       0 $self->load_subcommand( $ENV{VTIDE_DIR} ? 'edit' : 'start', $opt );
127 0         0 my ( undef, $dir ) = $subcommand->session_dir( $opt->cmd );
128 0 0       0 if ( !$dir ) {
129 0         0 my $error = $@;
130 0 0       0 warn $@ if $opt->opt->verbose;
131 0         0 warn "Unknown command '$cmd'!\n",
132             "Valid commands - ", ( join ', ', sort @sub_commands ),
133             "\n";
134 0         0 require Pod::Usage;
135 0         0 Pod::Usage::pod2usage(
136             -verbose => 1,
137             -input => __FILE__,
138             );
139             }
140 0         0 unshift @{ $opt->files }, $opt->cmd;
  0         0  
141             }
142              
143             $subcommand->options->default(
144 0         0 { %{$options}, %{ $subcommand->options->default } } );
  0         0  
  0         0  
145             eval {
146 0         0 $subcommand->run;
147 0         0 1;
148 0 0       0 } or do {
149 0         0 warn "Error running " . $opt->cmd . "!\n";
150 0         0 warn $@;
151 0         0 sleep 5;
152             };
153 0         0 return;
154             }
155              
156             sub load_subcommand {
157 1     1 1 142309 my ( $self, $cmd, $opt ) = @_;
158              
159 1         7 my $file = 'App/VTide/Command/' . ucfirst $cmd . '.pm';
160 1         4 my $module = 'App::VTide::Command::' . ucfirst $cmd;
161              
162 1         569 require $file;
163              
164 1         38 return $module->new(
165             defaults => $opt->opt,
166             options => $opt,
167             vtide => $self,
168             );
169             }
170              
171             sub _sub_commands {
172 0     0     my ($self) = @_;
173 0           my $sub_file = path $ENV{HOME}, '.vtide', 'sub-commands.yml';
174              
175 0 0         mkdir $sub_file->parent if !-d $sub_file->parent;
176              
177             #if ( -f $sub_file && path($0)->stat->mtime ne $sub_file->stat->mtime ) {
178             # unlink $sub_file;
179             #}
180              
181             #return LoadFile("$sub_file") if -f $sub_file;
182              
183 0           return $self->_generate_sub_command();
184             }
185              
186             sub _generate_sub_command {
187 0     0     my ($self) = @_;
188 0           my $sub_file = path $ENV{HOME}, '.vtide', 'sub-commands.yml';
189              
190 0           require Module::Pluggable;
191 0           Module::Pluggable->import(
192             require => 1,
193             search_path => ['App::VTide::Command']
194             );
195 0           my @commands = __PACKAGE__->plugins;
196              
197 0           my $sub_commands = {};
198 0           for my $command ( reverse sort @commands ) {
199 0           my ( $name, $conf ) = $command->details_sub;
200              
201 0           $sub_commands->{$name} = $conf;
202             }
203              
204 0           DumpFile( $sub_file, $sub_commands );
205              
206 0           return $sub_commands;
207             }
208              
209             1;
210              
211             __END__
212              
213             =head1 NAME
214              
215             App::VTide - A vim/tmux based IDE for the terminal
216              
217             =head1 VERSION
218              
219             This documentation refers to App::VTide version 1.0.4
220              
221             =head1 SYNOPSIS
222              
223             Session level
224             vtide init
225             vtide [start] [project]
226             With in a session
227             vtide (edit|run|conf|grep|recent|split|refresh|save|sessions|help) [options]
228              
229             COMMANDS:
230             conf Show editor config settings
231             edit Run vim for a group of files
232             grep Run grep against configured globs
233             help Show help for vtide sub commands
234             init Initialise a new project
235             recent List recently run vtide sessions
236             refresh Refreshes the autocomplete cache
237             run Run a projects terminal command
238             save Make/Save changes to a projects config file
239             sessions
240             run of save a session
241             split Simply split up a tmux widow (using the same syntax as the config)
242             start Open a project in Tmux
243              
244             Examples:
245             # start a new project, name taken from the directory name
246             vtide init
247             # start a new project specifying the project name
248             vtide init --name my-project
249             # start the project in the current directory
250             vtide start
251             # start the "my-project" project previously initialised
252             vtide start my-project
253             # Shortcuts
254             # When not in a tmux session starting a new session
255             vtide my-project
256             # When in a tmux session you can run edit with out specifying it
257             vtide my-glob
258              
259             =head1 DESCRIPTION
260              
261             VTide provides a way to manage L<tmux> sessions. It allows for an easy way
262             to configure a session window and run programs or open files for editing
263             in them. The aim is to allow for easy project setup and management for
264             projects managed on the command line. L<App::VTide> also includes helpers
265             for loading files into editors (such as vim) in separate tmux terminals.
266             This can help to open pre-defined groups of files.
267              
268             =head2 Philosophy
269              
270             One piece of work == one project == one terminal tab. In one terminal
271             tmux is run with tmux windows for editing different files, running commands
272             and version control work.
273              
274             =head1 SUBROUTINES/METHODS
275              
276             =head2 C<run ()>
277              
278             Run the vtide commands
279              
280             =head2 C<load_subcommand ( $cmd, $opt )>
281              
282             Loads the sub-command module and creates a new instance of it to return
283             to the caller.
284              
285             =head1 DIAGNOSTICS
286              
287             =head1 CONFIGURATION AND ENVIRONMENT
288              
289             A full description of the configuration files can be found in
290             L<App::VTide::Configuration>.
291              
292             =head1 DEPENDENCIES
293              
294             =head1 INCOMPATIBILITIES
295              
296             =head1 BUGS AND LIMITATIONS
297              
298             There are no known bugs in this module.
299              
300             Please report problems to Ivan Wills (ivan.wills@gmail.com).
301              
302             Patches are welcome.
303              
304             =head1 AUTHOR
305              
306             Ivan Wills - (ivan.wills@gmail.com)
307              
308             =head1 LICENSE AND COPYRIGHT
309              
310             Copyright (c) 2016 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077).
311             All rights reserved.
312              
313             This module is free software; you can redistribute it and/or modify it under
314             the same terms as Perl itself. See L<perlartistic>. This program is
315             distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
316             without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
317             PARTICULAR PURPOSE.
318              
319             =cut