| 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__ |