File Coverage

blib/lib/Text/Snippet/TabStop/Cursor.pm
Criterion Covered Total %
statement 66 67 98.5
branch 21 26 80.7
condition 13 19 68.4
subroutine 16 16 100.0
pod 9 9 100.0
total 125 137 91.2


line stmt bran cond sub pod time code
1             package Text::Snippet::TabStop::Cursor;
2             BEGIN {
3 8     8   1539 $Text::Snippet::TabStop::Cursor::VERSION = '0.04';
4             }
5              
6             # ABSTRACT: Provides a bi-directional iterator interface for moving from one tab-stop to it's siblings
7              
8 8     8   51 use strict;
  8         16  
  8         674  
9 8     8   45 use warnings;
  8         16  
  8         359  
10 8     8   950 use Class::XSAccessor getters => {snippet => 'snippet'};
  8         15811  
  8         72  
11 8     8   1713 use Scalar::Util qw(blessed refaddr);
  8         17  
  8         889  
12 8     8   50 use Carp qw(croak);
  8         17  
  8         32141  
13              
14              
15             sub new {
16 3     3 1 5 my $class = shift;
17 3         13 my %args = (i => -1, @_);
18 3 50       16 croak "snippet must be ISA Text::Snippet" unless blessed $args{snippet} eq 'Text::Snippet';
19 3         15 return bless \%args, $class;
20             }
21              
22             sub has_prev {
23 5     5 1 7 my $self = shift;
24 5         14 my $stops = $self->snippet->tab_stops;
25 5   33     61 return @$stops && $self->{i} > 0;
26             }
27              
28             sub prev {
29 5     5 1 8 my $self = shift;
30 5 50       12 return $self->has_prev ? $self->snippet->tab_stops->[ --$self->{i} ] : ();
31             }
32              
33             sub has_next {
34 20     20 1 73 my $self = shift;
35 20         50 my $stops = $self->snippet->tab_stops;
36 20   66     58 return @$stops && $self->{i} < $#{$stops};
37             }
38              
39             sub next {
40 12     12 1 36 my $self = shift;
41 12 50       23 return $self->has_next ? $self->snippet->tab_stops->[ ++$self->{i} ] : ();
42             }
43              
44             sub current {
45 102     102 1 153 my $self = shift;
46 102 100       395 return unless($self->{i} >= 0);
47 100         201 my $stops = $self->snippet->tab_stops;
48 100 50       227 if ( exists( $stops->[ $self->{i} ] ) ) {
49 100         233 return $stops->[ $self->{i} ];
50             }
51 0         0 return;
52             }
53              
54             sub _is_current {
55 82     82   114 my $self = shift;
56 82         144 my $current = $self->current;
57 82         121 my $tab_stop = shift;
58 82   66     681 return blessed($tab_stop) && (refaddr($tab_stop) == refaddr($current) || ($tab_stop->has_parent && refaddr($tab_stop->parent) == refaddr($current)));
59             }
60              
61             sub current_position {
62 8     8 1 19 my $self = shift;
63 8         18 my $current = $self->current;
64 8         15 my ($line, $column) = (0,0);
65 8 100       24 return [$line,$column] if ! defined $current;
66            
67 7         9 foreach my $c(@{ $self->snippet->chunks }){
  7         22  
68 41 100       86 last if($self->_is_current($c));
69 34 100 66     222 my $text = blessed($c) && $c->can('to_string') ? $c->to_string || '': "$c";
      100        
70 34         118 foreach my $char(split(/(\n)/,$text)){
71 40 100       72 if($char eq "\n"){
72 8         10 $line++;
73 8         13 $column = 0;
74             } else {
75 32         87 $column += length($char);
76             }
77             }
78             }
79 7         46 return [$line,$column];
80             }
81              
82             sub current_char_position {
83 8     8 1 15 my $self = shift;
84 8         11 my $pos = 0;
85 8         18 my $current = $self->current;
86 8 100       24 return $pos if ! defined $current;
87 7         10 foreach my $c( @{ $self->snippet->chunks } ){
  7         26  
88 41 100       80 last if($self->_is_current($c));
89 34 100 66     202 my $text = blessed($c) && $c->can('to_string') ? $c->to_string || '': "$c";
      100        
90 34         63 $pos += length($text);
91             }
92 7         32 return $pos;
93             }
94              
95             sub is_terminal {
96 2     2 1 10 my $self = shift;
97 2 50       6 return if(!defined$self->current);
98 2         5 return $self->current->index == 0;
99             }
100              
101             1;
102              
103             __END__