line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Term::ReadLine::Zoid::FileBrowse; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
2010
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
42
|
|
4
|
1
|
|
|
1
|
|
5
|
use base 'Term::ReadLine::Zoid'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
3961
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = 0.01; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our %_keymap = ( # maybe inherit from insert ? these could be remapped |
9
|
|
|
|
|
|
|
up => 'select_previous', |
10
|
|
|
|
|
|
|
down => 'select_next', |
11
|
|
|
|
|
|
|
right => 'select_next_col', |
12
|
|
|
|
|
|
|
left => 'select_previous_col', |
13
|
|
|
|
|
|
|
page_up => 'page_up', |
14
|
|
|
|
|
|
|
page_down => 'page_down', |
15
|
|
|
|
|
|
|
return => 'accept_line', |
16
|
|
|
|
|
|
|
ctrl_C => 'return_empty_string', |
17
|
|
|
|
|
|
|
escape => 'switch_mode', |
18
|
|
|
|
|
|
|
'/' => 'fb_mini_buffer', |
19
|
|
|
|
|
|
|
' ' => 'toggle_mark', |
20
|
|
|
|
|
|
|
'.' => 'toggle_hide_hidden', |
21
|
|
|
|
|
|
|
_default => 'self_insert', |
22
|
|
|
|
|
|
|
_on_switch => 'fb_switch', |
23
|
|
|
|
|
|
|
); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub keymap { |
26
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
27
|
0
|
|
|
|
|
|
for ( |
28
|
|
|
|
|
|
|
['hide_hidden_files', 1], |
29
|
|
|
|
|
|
|
['fb_prompt', "\e[1;37m -- \%s -- \e[0m"], |
30
|
|
|
|
|
|
|
) { |
31
|
0
|
0
|
|
|
|
|
$$self{config}{$$_[0]} = $$_[1] |
32
|
|
|
|
|
|
|
unless defined $$self{config}{$$_[0]} |
33
|
|
|
|
|
|
|
} |
34
|
0
|
|
|
|
|
|
return \%_keymap; |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# fb_item == item currently selected (pointed at) |
38
|
|
|
|
|
|
|
# fb_marks == marked _numbers_ in current dir |
39
|
|
|
|
|
|
|
# fb_marked == marked _items_ in other dirs |
40
|
|
|
|
|
|
|
# fb_items == items in current dir |
41
|
|
|
|
|
|
|
# fb_dir == current dir |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub fb_switch { |
44
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
45
|
0
|
|
|
|
|
|
@$self{qw/fb_item fb_marks fb_marked fb_items/} = (0, [], [], []); |
46
|
0
|
|
|
|
|
|
$self->fb_switch_dir('.'); |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub fb_switch_dir { # FIXME FIXME "marked" admisnistrationis contains bugs |
50
|
0
|
|
|
0
|
0
|
|
my ($self, $dir) = @_; |
51
|
0
|
|
0
|
|
|
|
$dir ||= $$self{fb_dir}; |
52
|
0
|
|
|
|
|
|
my $pwd; |
53
|
0
|
0
|
|
|
|
|
if ($dir eq '.') { $dir = $ENV{PWD}; $pwd++; } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
else { |
55
|
0
|
|
|
|
|
|
$dir =~ s#^\./#$ENV{PWD}#; |
56
|
0
|
|
|
|
|
|
$dir =~ s#/\.(/|$)|//+#/#g; |
57
|
0
|
|
|
|
|
|
$dir =~ s#(^|/)[^/]*/\.\.(/|$)##g; |
58
|
0
|
|
|
|
|
|
$dir =~ s#/?$#/#; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
0
|
0
|
|
|
|
|
opendir DIR, $dir or return $self->bell; |
62
|
0
|
|
|
|
|
|
my (@marks, @marked); |
63
|
0
|
|
|
|
|
|
for ($self->marked()) { |
64
|
0
|
0
|
|
|
|
|
if (m#(.*/)(.*)#) { |
|
|
0
|
|
|
|
|
|
65
|
0
|
0
|
|
|
|
|
if ($1 eq $dir) { push @marks, $2 } |
|
0
|
|
|
|
|
|
|
66
|
0
|
|
|
|
|
|
else { push @marked, $_ } |
67
|
|
|
|
|
|
|
} |
68
|
0
|
|
|
|
|
|
elsif ($pwd) { push @marks, $_ } |
69
|
0
|
|
|
|
|
|
else { push @marked, $_ } |
70
|
|
|
|
|
|
|
} |
71
|
0
|
0
|
|
|
|
|
$$self{fb_items} = [ '../', |
72
|
0
|
|
|
|
|
|
map {-d "$dir/$_" ? $_.'/' : $_} |
73
|
|
|
|
|
|
|
$$self{config}{hide_hidden_files} |
74
|
0
|
|
|
|
|
|
? (sort grep {$_ !~ /^\./ } readdir DIR) |
75
|
0
|
0
|
|
|
|
|
: (sort grep {$_ !~ /^\.\.?$/} readdir DIR) |
76
|
|
|
|
|
|
|
]; |
77
|
0
|
|
|
|
|
|
close DIR; |
78
|
0
|
|
|
|
|
|
$$self{fb_marked} = \@marked; |
79
|
0
|
|
|
|
|
|
$$self{fb_marks} = []; |
80
|
0
|
0
|
|
|
|
|
if (@marks) { |
81
|
0
|
|
|
|
|
|
my $i = 0; |
82
|
0
|
|
|
|
|
|
for my $item (@{$$self{fb_items}}) { |
|
0
|
|
|
|
|
|
|
83
|
0
|
|
|
|
|
|
push @{$$self{fb_marks}}, $i |
|
0
|
|
|
|
|
|
|
84
|
0
|
0
|
|
|
|
|
if grep {$_ eq $item} @marks; |
85
|
0
|
|
|
|
|
|
$i++; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
} |
88
|
0
|
|
|
|
|
|
@$self{qw/fb_item fb_dir/} = (0, $dir); |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub draw { # Render Fu |
92
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
93
|
|
|
|
|
|
|
|
94
|
0
|
|
|
|
|
|
my @pos = (1, 1); |
95
|
0
|
|
|
|
|
|
my @lines = map " $_", @{$$self{fb_items}}; |
|
0
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
|
for (@{$$self{fb_marks}}) { $lines[$_] =~ s/^ /*/ } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
97
|
0
|
|
|
|
|
|
$lines[ $$self{fb_item} ] =~ s/^(.) /$1>/; |
98
|
|
|
|
|
|
|
|
99
|
0
|
|
|
|
|
|
@lines = $self->col_format( @lines ); |
100
|
0
|
|
|
|
|
|
$$self{fb_rows} = scalar @lines; |
101
|
0
|
|
|
|
|
|
$pos[1] += ($$self{fb_item} % $$self{fb_rows}); # assuming +1 offset due to fb_prompt |
102
|
|
|
|
|
|
|
|
103
|
0
|
|
|
|
|
|
unshift @lines, sprintf $$self{config}{fb_prompt}, $$self{fb_dir}; |
104
|
|
|
|
|
|
|
|
105
|
0
|
|
|
|
|
|
$self->print(\@lines, \@pos); |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub toggle_hide_hidden { |
109
|
0
|
0
|
|
0
|
0
|
|
$_[0]{config}{hide_hidden_files} = |
110
|
|
|
|
|
|
|
$_[0]{config}{hide_hidden_files} ? 0 : 1 ; |
111
|
0
|
|
|
|
|
|
$_[0]->fb_switch_dir(); |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub self_insert { |
115
|
0
|
|
|
0
|
0
|
|
my ($self, $key) = @_; |
116
|
0
|
0
|
|
|
|
|
return $self->bell unless $key =~ /^\d+$/; |
117
|
|
|
|
|
|
|
#$$self{fb_item} .= $key; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub accept_line { |
121
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
122
|
0
|
|
|
|
|
|
my $dir = $$self{fb_dir}.'/'.$$self{fb_items}[ $$self{fb_item} ]; |
123
|
0
|
0
|
|
|
|
|
return $self->fb_switch_dir($dir) if -d $dir; |
124
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
push @{$$self{fb_marks}}, $$self{fb_item}; |
|
0
|
|
|
|
|
|
|
126
|
0
|
|
|
|
|
|
my @words = map {s/'/\\'/g; '\''.$_.'\''} $self->marked(); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
127
|
0
|
|
|
|
|
|
$self->substring(join(' ', @words), $$self{pos}); |
128
|
0
|
|
|
|
|
|
$self->switch_mode(); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub fb_mini_buffer { |
132
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
0
|
0
|
|
0
|
0
|
|
sub select_next { $_[0]{fb_item}++ if $_[0]{fb_item} < $#{$_[0]{fb_items}} } |
|
0
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub page_up { |
138
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
139
|
0
|
|
|
|
|
|
my (undef, $higth) = $self->TermSize(); |
140
|
0
|
|
|
|
|
|
my $vpos = $$self{fb_item} % $$self{fb_rows}; |
141
|
0
|
0
|
|
|
|
|
if ($vpos > $higth) { $$self{fb_item} -= $higth } |
|
0
|
|
|
|
|
|
|
142
|
0
|
|
|
|
|
|
else { $$self{fb_item} -= $vpos } |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub page_down { |
146
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
147
|
0
|
|
|
|
|
|
my (undef, $higth) = $self->TermSize(); |
148
|
0
|
|
|
|
|
|
my $rvpos = $$self{fb_rows} - ($$self{fb_item} % $$self{fb_rows}); |
149
|
0
|
0
|
|
|
|
|
if ($rvpos > $higth) { $$self{fb_item} += $higth } |
|
0
|
|
|
|
|
|
|
150
|
0
|
|
|
|
|
|
else { $$self{fb_item} += $rvpos } |
151
|
0
|
0
|
|
|
|
|
$$self{fb_item} = $#{$$self{fb_items}} if $$self{fb_item} > $#{$$self{fb_items}}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
0
|
0
|
|
0
|
0
|
|
sub select_previous { $_[0]{fb_item}-- if $_[0]{fb_item} > 0 } |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub select_next_col { |
157
|
0
|
|
|
|
|
|
$_[0]{fb_item} += $_[0]{fb_rows} |
158
|
0
|
0
|
|
0
|
0
|
|
unless $_[0]{fb_rows} > $#{$_[0]{fb_items}} - $_[0]{fb_item}; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub select_previous_col { |
162
|
0
|
0
|
|
0
|
0
|
|
$_[0]{fb_item} -= $_[0]{fb_rows} |
163
|
|
|
|
|
|
|
unless $_[0]{fb_rows} > $_[0]{fb_item}; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub toggle_mark { # FIXME should be toggle |
167
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
168
|
0
|
|
|
|
|
|
my $l = scalar @{$$self{fb_marks}}; |
|
0
|
|
|
|
|
|
|
169
|
0
|
|
|
|
|
|
@{$$self{fb_marks}} = grep {$_ != $$self{fb_item}} @{$$self{fb_marks}}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
170
|
0
|
0
|
|
|
|
|
push @{$$self{fb_marks}}, $$self{fb_item} if $l == scalar @{$$self{fb_marks}}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
171
|
0
|
|
|
|
|
|
$self->select_next(); |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub marked { |
175
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
176
|
0
|
|
|
|
|
|
my $dir = $$self{fb_dir}; |
177
|
0
|
|
|
|
|
|
$dir =~ s#^\Q$ENV{PWD}\E/?##; |
178
|
0
|
0
|
|
|
|
|
$dir =~ s#/?$#/# if length $dir; |
179
|
0
|
|
|
|
|
|
return @{$$self{fb_marked}}, |
|
0
|
|
|
|
|
|
|
180
|
0
|
|
|
|
|
|
map $dir.$_, @{$$self{fb_items}}[ @{$$self{fb_marks}} ]; |
|
0
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
1; |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
__END__ |