rfd 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +128 -3
- data/lib/rfd.rb +37 -40
- data/lib/rfd/commands.rb +2 -2
- data/lib/rfd/item.rb +8 -0
- data/lib/rfd/windows.rb +4 -1
- data/rfd.gemspec +1 -1
- data/spec/controller_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfede93c56a43d3df90257d60df31b8934b6891f
|
4
|
+
data.tar.gz: d5187481f8cb6076394a4337ae85a1799120f2a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 427efc2d0a2a5e6fba9e4ad7de07dc791b335e6b59ca0f21c62dd3760999816d338f58cd233eddcc80c8849232302808911d447878b3cd1824765e872cba5044
|
7
|
+
data.tar.gz: 4f41128bcd148e16149a4ce40ea1485be8e11b989bcb280a69e31074088e50865488097434ecfaa0daf623218df09723454ee5789f9132c56a4740d69f632105
|
data/README.md
CHANGED
@@ -16,15 +16,140 @@ rfd is a terminal based File explorer, inpsired by the legendary freesoft MS-DOS
|
|
16
16
|
|
17
17
|
Mac OS X Mountain Lion, Mac OS X Lion
|
18
18
|
|
19
|
-
##
|
19
|
+
## Screenshot
|
20
|
+
|
21
|
+

|
22
|
+
|
23
|
+
## Start Me Up
|
20
24
|
|
21
25
|
Open up your terminal and type in:
|
22
26
|
|
23
27
|
% rfd
|
24
28
|
|
25
|
-
You can
|
29
|
+
You can also pass in a starting directory name, which is defaulted to `.`.
|
30
|
+
|
31
|
+
% rfd ~/src/rails
|
32
|
+
|
33
|
+
## Commands
|
34
|
+
|
35
|
+
You can command rfd by pressing some chars on your keyboard, just like Vim. If you're totally unfamiliar with this sort of command system, I recommend you to play with `vimtutor` before you go any further.
|
36
|
+
|
37
|
+
All available commands in rfd are defined as Ruby methods here. https://github.com/amatsuda/rfd/tree/master/lib/rfd/commands.rb
|
38
|
+
|
39
|
+
### Changing the current directory
|
40
|
+
|
41
|
+
* **\<Enter\>**: cd into the directory where the cursor is on.
|
42
|
+
* **\<Delete\>** (or \<Backspace\> on you keyboard, probably?): Go up to the upper directory (cd ..).
|
43
|
+
* **-**: Get back to where you once belonged (popd).
|
44
|
+
|
45
|
+
### Moving the cursor
|
46
|
+
|
47
|
+
* **j**: Move downward.
|
48
|
+
* **k**: Move upward.
|
49
|
+
* **h**: Move to the left column. At the left end column, move to the right end column at the previous page.
|
50
|
+
* **l**: Move to the right column. At the right end column, move to the left end column at the next page.
|
51
|
+
|
52
|
+
### The {count} parameter
|
53
|
+
|
54
|
+
Some commands such as `j` or `k` take a number parameter called {count}. For passing a {count} parameter, just type in a number prior to the command.
|
55
|
+
For example, `3j` moves the cursor to 3 lines below, and `999k` will take your cursor to 999 lines above.
|
56
|
+
|
57
|
+
### Jumping the cursor
|
58
|
+
|
59
|
+
* **H**: Move to the top of the current page.
|
60
|
+
* **M**: Move to the middle of the current page.
|
61
|
+
* **L**: Move to the bottom of the current page.
|
62
|
+
|
63
|
+
### Switching the page
|
64
|
+
|
65
|
+
* **ctrl-n, ctrl-f**: Move to the top of the next page.
|
66
|
+
* **ctrl-p, ctrl-b**: Move to the top of the previous page.
|
67
|
+
* **g**: Move to the top of the first page.
|
68
|
+
* **G**: Move to the bottom of the last page.
|
69
|
+
|
70
|
+
### Finding a file / directory
|
71
|
+
|
72
|
+
You can find a file by typing the first letter of it immediately after the find commands.
|
73
|
+
|
74
|
+
* **f{char}**: Move to the next file / directory of which name starts with the given char.
|
75
|
+
* **F{char}**: Move to the previous file / directory of which name starts with the given char.
|
76
|
+
* **n**: Repeat the last `f` or `F`.
|
77
|
+
|
78
|
+
### Searching, sorting
|
79
|
+
|
80
|
+
For commands like these that require a parameter string, type the parameter in the command line at the bottom of the screen, and press \<Enter\>.
|
81
|
+
|
82
|
+
* **/**: Grep the current directory with the given parameter. The parameter will be interpreted as Ruby Regexp (e.g. `.*\.rb$`).
|
83
|
+
* **s**: Sort files / directories in the current directory in the given order.
|
84
|
+
* (none): by name
|
85
|
+
* r : reverse order by name
|
86
|
+
* s, S : order by file size
|
87
|
+
* sr, Sr: reverse order by file size
|
88
|
+
* t : order by mtime
|
89
|
+
* tr : reverse order by mtime
|
90
|
+
* c : order by ctime
|
91
|
+
* cr : reverse order by ctime
|
92
|
+
* u : order by atime
|
93
|
+
* ur : reverse order by atime
|
94
|
+
* e : order by extname
|
95
|
+
* er : reverse order by extname
|
96
|
+
|
97
|
+
### Marking files / directories
|
98
|
+
|
99
|
+
You can send a command to the file / directory on which the cursor is on. Or, you can send a command to multiple files / directories at once by marking them first.
|
100
|
+
The mark is drawn as a `*` char on the left of each file / directory name.
|
101
|
+
|
102
|
+
* **\<Space\>**: Mark / unmark current file / directory.
|
103
|
+
* **ctrl-a**: Mark / unmark all file / directories in the current directory.
|
104
|
+
|
105
|
+
### Manipulating files / directories
|
106
|
+
|
107
|
+
As stated above, you can send a command to one or more files / directories. In this document, the term "selected items" means "(the marked files / directories) || (the file / directory on which the cursor is on)".
|
108
|
+
|
109
|
+
* **c**: Copy selected items (cp).
|
110
|
+
* **m**: Move selected items (mv).
|
111
|
+
* **d**: Move selected items into the Trash.
|
112
|
+
* **D**: Delete selected items.
|
113
|
+
* **r**: Rename selected items.
|
114
|
+
|
115
|
+
### Creating files / directories
|
116
|
+
|
117
|
+
* **t**: Create a new file (touch).
|
118
|
+
* **K**: Creat a new directory (mkdir).
|
119
|
+
* **S**: Create new symlink to the current file / directory (ln -s).
|
120
|
+
|
121
|
+
### Attributes
|
122
|
+
|
123
|
+
* **a**: Change permission of selected items (chmod).
|
124
|
+
* **w**: Change the owner of of selected items (chown).
|
125
|
+
|
126
|
+
### Viewing, Editing, Opening
|
127
|
+
|
128
|
+
* **\<Enter\>**: View current file with the system $VIEWER such as `less`.
|
129
|
+
* **v**: View current file with the system $VIEWER such as `less`.
|
130
|
+
* **e**: Edit current file with the system $EDITOR such as `vim`.
|
131
|
+
* **o**: Send the `open` command.
|
132
|
+
|
133
|
+
### Manipulating archives
|
134
|
+
|
135
|
+
* **u**: Unarchive .zip, .gz, or .tar.gz file into the current directory.
|
136
|
+
* **z**: Archive selected items into a .zip file with the given name.
|
137
|
+
|
138
|
+
### Handling .zip files
|
139
|
+
|
140
|
+
You can `cd` into a .zip file as if it's just a directory, then unarchive selected items, view files in it, and even create new files or edit files in the archive.
|
141
|
+
|
142
|
+
### Splitting columns
|
143
|
+
|
144
|
+
* **ctrl-w**: Change the window split size to the {count} value (e.g. `4<C-w>` to split the window into 4 columns). The default number of columns is 2.
|
145
|
+
|
146
|
+
### Misc
|
26
147
|
|
27
|
-
|
148
|
+
* **ctrl-l**: Refresh the whole screen.
|
149
|
+
* **C**: Copy selected items' paths to the clipboard.
|
150
|
+
* **O**: Open a new terminal window at the current directory.
|
151
|
+
* **!**: Execute a shell command.
|
152
|
+
* **q**: Quit the app.
|
28
153
|
|
29
154
|
## Contributing
|
30
155
|
|
data/lib/rfd.rb
CHANGED
@@ -171,23 +171,15 @@ module Rfd
|
|
171
171
|
|
172
172
|
# Change the current directory.
|
173
173
|
def cd(dir, pushd: true)
|
174
|
-
|
175
|
-
|
174
|
+
dir = load_item expand_path(dir) unless dir.is_a? Item
|
175
|
+
unless dir.zip?
|
176
|
+
Dir.chdir dir
|
177
|
+
@current_zip = nil
|
176
178
|
else
|
177
|
-
|
178
|
-
if File.readable? target
|
179
|
-
Dir.chdir target
|
180
|
-
@dir_history << current_dir if current_dir && pushd
|
181
|
-
@current_dir, @current_page, @current_row, @current_zip = target, 0, nil, nil
|
182
|
-
main.activate_pane 0
|
183
|
-
end
|
179
|
+
@current_zip = dir
|
184
180
|
end
|
185
|
-
|
186
|
-
|
187
|
-
def cd_into_zip(zipfile)
|
188
|
-
@current_zip = zipfile
|
189
|
-
@dir_history << current_dir if current_dir
|
190
|
-
@current_dir, @current_page, @current_row = zipfile.path, 0, nil
|
181
|
+
@dir_history << current_dir if current_dir && pushd
|
182
|
+
@current_dir, @current_page, @current_row = dir, 0, nil
|
191
183
|
main.activate_pane 0
|
192
184
|
end
|
193
185
|
|
@@ -266,7 +258,7 @@ module Rfd
|
|
266
258
|
def fetch_items_from_filesystem_or_zip
|
267
259
|
unless in_zip?
|
268
260
|
@items = Dir.foreach(current_dir).map {|fn|
|
269
|
-
stat = File.lstat
|
261
|
+
stat = File.lstat current_dir.join(fn)
|
270
262
|
Item.new dir: current_dir, name: fn, stat: stat, window_width: maxx
|
271
263
|
}.to_a
|
272
264
|
else
|
@@ -311,7 +303,7 @@ module Rfd
|
|
311
303
|
# Update the main window with the loaded files and directories. Also update the header.
|
312
304
|
def draw_items
|
313
305
|
main.draw_items_to_each_pane (@displayed_items = items[current_page * max_items, max_items])
|
314
|
-
header_l.draw_path_and_page_number path: current_dir, current: current_page + 1, total: total_pages
|
306
|
+
header_l.draw_path_and_page_number path: current_dir.path, current: current_page + 1, total: total_pages
|
315
307
|
end
|
316
308
|
|
317
309
|
# Sort the loaded files and directories in already given sort order.
|
@@ -367,11 +359,11 @@ module Rfd
|
|
367
359
|
# Copy selected files and directories to the destination.
|
368
360
|
def cp(dest)
|
369
361
|
unless in_zip?
|
370
|
-
src = (m = marked_items).any? ? m.map(&:path) : current_item
|
362
|
+
src = (m = marked_items).any? ? m.map(&:path) : current_item
|
371
363
|
FileUtils.cp_r src, expand_path(dest)
|
372
364
|
else
|
373
365
|
raise 'cping multiple items in .zip is not supported.' if selected_items.size > 1
|
374
|
-
Zip::File.open(current_zip
|
366
|
+
Zip::File.open(current_zip) do |zip|
|
375
367
|
entry = zip.find_entry(selected_items.first.name).dup
|
376
368
|
entry.name, entry.name_length = dest, dest.size
|
377
369
|
zip.instance_variable_get(:@entry_set) << entry
|
@@ -383,7 +375,7 @@ module Rfd
|
|
383
375
|
# Move selected files and directories to the destination.
|
384
376
|
def mv(dest)
|
385
377
|
unless in_zip?
|
386
|
-
src = (m = marked_items).any? ? m.map(&:path) : current_item
|
378
|
+
src = (m = marked_items).any? ? m.map(&:path) : current_item
|
387
379
|
FileUtils.mv src, expand_path(dest)
|
388
380
|
else
|
389
381
|
raise 'mving multiple items in .zip is not supported.' if selected_items.size > 1
|
@@ -402,10 +394,10 @@ module Rfd
|
|
402
394
|
unless in_zip?
|
403
395
|
selected_items.each do |item|
|
404
396
|
name = item.name.gsub from, to
|
405
|
-
FileUtils.mv item
|
397
|
+
FileUtils.mv item, current_dir.join(name) if item.name != name
|
406
398
|
end
|
407
399
|
else
|
408
|
-
Zip::File.open(current_zip
|
400
|
+
Zip::File.open(current_zip) do |zip|
|
409
401
|
selected_items.each do |item|
|
410
402
|
name = item.name.gsub from, to
|
411
403
|
zip.rename item.name, name
|
@@ -439,7 +431,7 @@ module Rfd
|
|
439
431
|
unless in_zip?
|
440
432
|
FileUtils.rm_rf selected_items.map(&:path)
|
441
433
|
else
|
442
|
-
Zip::File.open(current_zip
|
434
|
+
Zip::File.open(current_zip) do |zip|
|
443
435
|
zip.select {|e| selected_items.map(&:name).include? e.to_s}.each do |entry|
|
444
436
|
if entry.name_is_directory?
|
445
437
|
zip.dir.delete entry.to_s
|
@@ -456,9 +448,9 @@ module Rfd
|
|
456
448
|
# Create a new directory.
|
457
449
|
def mkdir(dir)
|
458
450
|
unless in_zip?
|
459
|
-
FileUtils.mkdir_p
|
451
|
+
FileUtils.mkdir_p current_dir.join(dir)
|
460
452
|
else
|
461
|
-
Zip::File.open(current_zip
|
453
|
+
Zip::File.open(current_zip) do |zip|
|
462
454
|
zip.dir.mkdir dir
|
463
455
|
end
|
464
456
|
end
|
@@ -468,11 +460,11 @@ module Rfd
|
|
468
460
|
# Create a new empty file.
|
469
461
|
def touch(filename)
|
470
462
|
unless in_zip?
|
471
|
-
FileUtils.touch
|
463
|
+
FileUtils.touch current_dir.join(filename)
|
472
464
|
else
|
473
|
-
Zip::File.open(current_zip
|
465
|
+
Zip::File.open(current_zip) do |zip|
|
474
466
|
# zip.file.open(filename, 'w') {|_f| } #HAXX this code creates an unneeded temporary file
|
475
|
-
zip.instance_variable_get(:@entry_set) << Zip::Entry.new(current_zip
|
467
|
+
zip.instance_variable_get(:@entry_set) << Zip::Entry.new(current_zip, filename)
|
476
468
|
end
|
477
469
|
end
|
478
470
|
ls
|
@@ -480,7 +472,7 @@ module Rfd
|
|
480
472
|
|
481
473
|
# Create a symlink to the current file or directory.
|
482
474
|
def symlink(name)
|
483
|
-
FileUtils.ln_s current_item
|
475
|
+
FileUtils.ln_s current_item, name
|
484
476
|
ls
|
485
477
|
end
|
486
478
|
|
@@ -498,11 +490,11 @@ module Rfd
|
|
498
490
|
selected_items.each do |item|
|
499
491
|
next if item.symlink?
|
500
492
|
if item.directory?
|
501
|
-
Dir[
|
493
|
+
Dir[item.join('**/**')].each do |file|
|
502
494
|
zipfile.add file.sub("#{current_dir}/", ''), file
|
503
495
|
end
|
504
496
|
else
|
505
|
-
zipfile.add item.name, item
|
497
|
+
zipfile.add item.name, item
|
506
498
|
end
|
507
499
|
end
|
508
500
|
end
|
@@ -514,18 +506,18 @@ module Rfd
|
|
514
506
|
unless in_zip?
|
515
507
|
zips, gzs = selected_items.partition(&:zip?).tap {|z, others| break [z, *others.partition(&:gz?)]}
|
516
508
|
zips.each do |item|
|
517
|
-
FileUtils.mkdir_p
|
518
|
-
Zip::File.open(item
|
509
|
+
FileUtils.mkdir_p current_dir.join(item.basename)
|
510
|
+
Zip::File.open(item) do |zip|
|
519
511
|
zip.each do |entry|
|
520
|
-
FileUtils.mkdir_p File.join(
|
512
|
+
FileUtils.mkdir_p File.join(item.basename, File.dirname(entry.to_s))
|
521
513
|
zip.extract(entry, File.join(item.basename, entry.to_s)) { true }
|
522
514
|
end
|
523
515
|
end
|
524
516
|
end
|
525
517
|
gzs.each do |item|
|
526
|
-
Zlib::GzipReader.open(item
|
518
|
+
Zlib::GzipReader.open(item) do |gz|
|
527
519
|
Gem::Package::TarReader.new(gz) do |tar|
|
528
|
-
dest_dir =
|
520
|
+
dest_dir = current_dir.join (gz.orig_name || item.basename).sub(/\.tar$/, '')
|
529
521
|
tar.each do |entry|
|
530
522
|
dest = nil
|
531
523
|
if entry.full_name == '././@LongLink'
|
@@ -551,7 +543,7 @@ module Rfd
|
|
551
543
|
end
|
552
544
|
end
|
553
545
|
else
|
554
|
-
Zip::File.open(current_zip
|
546
|
+
Zip::File.open(current_zip) do |zip|
|
555
547
|
zip.select {|e| selected_items.map(&:name).include? e.to_s}.each do |entry|
|
556
548
|
FileUtils.mkdir_p File.join(current_zip.dir, current_zip.basename, File.dirname(entry.to_s))
|
557
549
|
zip.extract(entry, File.join(current_zip.dir, current_zip.basename, entry.to_s)) { true }
|
@@ -662,7 +654,7 @@ module Rfd
|
|
662
654
|
else
|
663
655
|
begin
|
664
656
|
tmpdir, tmpfile_name = nil
|
665
|
-
Zip::File.open(current_zip
|
657
|
+
Zip::File.open(current_zip) do |zip|
|
666
658
|
tmpdir = Dir.mktmpdir
|
667
659
|
FileUtils.mkdir_p File.join(tmpdir, File.dirname(current_item.name))
|
668
660
|
tmpfile_name = File.join(tmpdir, current_item.name)
|
@@ -687,7 +679,7 @@ module Rfd
|
|
687
679
|
else
|
688
680
|
begin
|
689
681
|
tmpdir, tmpfile_name = nil
|
690
|
-
Zip::File.open(current_zip
|
682
|
+
Zip::File.open(current_zip) do |zip|
|
691
683
|
tmpdir = Dir.mktmpdir
|
692
684
|
FileUtils.mkdir_p File.join(tmpdir, File.dirname(current_item.name))
|
693
685
|
tmpfile_name = File.join(tmpdir, current_item.name)
|
@@ -720,7 +712,12 @@ module Rfd
|
|
720
712
|
end
|
721
713
|
|
722
714
|
def expand_path(path)
|
723
|
-
File.expand_path path.
|
715
|
+
File.expand_path path.start_with?('/') || path.start_with?('~') ? path : current_dir ? current_dir.join(path) : path
|
716
|
+
end
|
717
|
+
|
718
|
+
def load_item(path)
|
719
|
+
stat = File.lstat path
|
720
|
+
Item.new dir: File.dirname(path), name: File.basename(path), stat: stat, window_width: maxx
|
724
721
|
end
|
725
722
|
|
726
723
|
def osx?
|
data/lib/rfd/commands.rb
CHANGED
@@ -266,8 +266,8 @@ module Rfd
|
|
266
266
|
|
267
267
|
# cd to the upper hierarchy.
|
268
268
|
def del
|
269
|
-
if current_dir != '/'
|
270
|
-
cd File.expand_path(
|
269
|
+
if current_dir.path != '/'
|
270
|
+
cd File.expand_path(current_dir.join(['..'] * times))
|
271
271
|
ls
|
272
272
|
end
|
273
273
|
end
|
data/lib/rfd/item.rb
CHANGED
@@ -20,6 +20,10 @@ module Rfd
|
|
20
20
|
@extname ||= File.extname name
|
21
21
|
end
|
22
22
|
|
23
|
+
def join(*ary)
|
24
|
+
File.join path, ary
|
25
|
+
end
|
26
|
+
|
23
27
|
def full_display_name
|
24
28
|
n = @name.dup
|
25
29
|
n << " -> #{target}" if symlink?
|
@@ -187,6 +191,10 @@ module Rfd
|
|
187
191
|
"#{current_mark}#{mb_ljust(display_name, @window_width - 15)}#{size_or_dir.rjust(13)}"
|
188
192
|
end
|
189
193
|
|
194
|
+
def to_str
|
195
|
+
path
|
196
|
+
end
|
197
|
+
|
190
198
|
def <=>(o)
|
191
199
|
if directory? && !o.directory?
|
192
200
|
1
|
data/lib/rfd/windows.rb
CHANGED
data/rfd.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "rfd"
|
7
|
-
spec.version = '0.
|
7
|
+
spec.version = '0.3.0'
|
8
8
|
spec.authors = ["Akira Matsuda"]
|
9
9
|
spec.email = ["ronnie@dio.jp"]
|
10
10
|
spec.description = 'Ruby on Files & Directories'
|
data/spec/controller_spec.rb
CHANGED
@@ -106,13 +106,13 @@ describe Rfd::Controller do
|
|
106
106
|
before do
|
107
107
|
controller.cd 'dir1'
|
108
108
|
end
|
109
|
-
its(
|
109
|
+
its('current_dir.path') { should == File.join(tmpdir, 'dir1') }
|
110
110
|
|
111
111
|
describe '#popd' do
|
112
112
|
before do
|
113
113
|
controller.popd
|
114
114
|
end
|
115
|
-
its(
|
115
|
+
its('current_dir.path') { should == tmpdir }
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rfd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akira Matsuda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi-ncurses
|