rfd 0.6.9 → 0.7.1
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/bin/rfd +4 -1
- data/lib/rfd/commands.rb +5 -0
- data/lib/rfd/item.rb +3 -5
- data/lib/rfd/logging.rb +34 -0
- data/lib/rfd/windows.rb +21 -7
- data/lib/rfd.rb +23 -7
- data/rfd.gemspec +9 -6
- metadata +35 -56
- data/spec/controller_spec.rb +0 -439
- data/spec/spec_helper.rb +0 -7
- data/spec/support/capture_helper.rb +0 -22
- data/spec/testdir/.file1 +0 -0
- data/spec/testdir/.file2 +0 -0
- data/spec/testdir/.file3 +0 -0
- data/spec/testdir/.link1 +0 -1
- data/spec/testdir/dir1/.keep +0 -0
- data/spec/testdir/dir2/.keep +0 -0
- data/spec/testdir/dir3/.keep +0 -0
- data/spec/testdir/dirlink1 +0 -1
- data/spec/testdir/file1 +0 -1
- data/spec/testdir/file2 +0 -0
- data/spec/testdir/file3 +0 -0
- data/spec/testdir/gz1.tar.gz +0 -0
- data/spec/testdir/link1 +0 -1
- data/spec/testdir/link2 +0 -1
- data/spec/testdir/zip1.zip +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d3f9431d82b51b60a0202b8715d7c70258127130a1006f1467bfb024a729cf9
|
4
|
+
data.tar.gz: 998e2b8409539ef0f2a0dcc9f50d39d8d200530a8a729020585ea627bc53d090
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 619e350f6ab323070af91f516591659da3ebb5abe3a27780ce63644200cf171667bdba5ab4dfd1ccbfa3bcfa7c9a482c9f76d7eb154232124ac3bc2428cc4835
|
7
|
+
data.tar.gz: b75b5c0ea0fea5daf59ec6dec75fbee332432cceae5ddd65f31d777ee4d485f1f47b1cd14239e644d532779eb6b52b6ff323cd110093f252d77cf49072a07617
|
data/bin/rfd
CHANGED
data/lib/rfd/commands.rb
CHANGED
@@ -186,6 +186,11 @@ module Rfd
|
|
186
186
|
process_command_line preset_command: 'symlink'
|
187
187
|
end
|
188
188
|
|
189
|
+
# "T"ouch the current file. This updates current item's timestamp (equivalent to `touch -t`).
|
190
|
+
def T
|
191
|
+
process_command_line preset_command: 'touch_t', default_argument: current_item.mtime.tr(': -', '')
|
192
|
+
end
|
193
|
+
|
189
194
|
# Mark or unmark "a"ll files and directories.
|
190
195
|
def ctrl_a
|
191
196
|
mark = marked_items.size != (items.size - 2) # exclude . and ..
|
data/lib/rfd/item.rb
CHANGED
@@ -37,12 +37,10 @@ module Rfd
|
|
37
37
|
n = full_display_name
|
38
38
|
if mb_size(n) <= @window_width - 15
|
39
39
|
n
|
40
|
+
elsif symlink?
|
41
|
+
mb_left n, @window_width - 16
|
40
42
|
else
|
41
|
-
|
42
|
-
mb_left n, @window_width - 16
|
43
|
-
else
|
44
|
-
"#{mb_left(basename, @window_width - 16 - extname.size)}…#{extname}"
|
45
|
-
end
|
43
|
+
"#{mb_left(basename, @window_width - 16 - extname.size)}…#{extname}"
|
46
44
|
end
|
47
45
|
end
|
48
46
|
end
|
data/lib/rfd/logging.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module Rfd
|
6
|
+
@logger = nil
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def log_to(file)
|
10
|
+
@logger = Logger.new file
|
11
|
+
@logger.debug 'hello'
|
12
|
+
|
13
|
+
Rfd::Controller.include Logging
|
14
|
+
end
|
15
|
+
|
16
|
+
def log(str)
|
17
|
+
Rfd.logger.debug str if Rfd.logger
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :logger
|
21
|
+
end
|
22
|
+
|
23
|
+
module Logging
|
24
|
+
def self.included(m)
|
25
|
+
mod = Module.new do
|
26
|
+
(m.instance_methods - Object.instance_methods).each do |meth|
|
27
|
+
Rfd.logger.info meth
|
28
|
+
define_method(meth) {|*args, &block| Rfd.logger.debug "calling #{meth}(#{args.inspect})"; super(*args, &block) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
m.prepend mod
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/rfd/windows.rb
CHANGED
@@ -56,12 +56,12 @@ module Rfd
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def draw_marked_items(count: 0, size: 0)
|
59
|
-
writeln 0, %Q[#{"#{count}Marked".rjust(11)} #{size.to_s.reverse.gsub(
|
59
|
+
writeln 0, %Q[#{"#{count}Marked".rjust(11)} #{size.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\1,').reverse.rjust(16)}]
|
60
60
|
noutrefresh
|
61
61
|
end
|
62
62
|
|
63
63
|
def draw_total_items(count: 0, size: 0)
|
64
|
-
writeln 1, %Q[#{"#{count}Files".rjust(10)} #{size.to_s.reverse.gsub(
|
64
|
+
writeln 1, %Q[#{"#{count}Files".rjust(10)} #{size.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\1,').reverse.rjust(17)}]
|
65
65
|
noutrefresh
|
66
66
|
end
|
67
67
|
end
|
@@ -147,15 +147,29 @@ module Rfd
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
-
def getstr_with_echo
|
151
|
-
str =
|
150
|
+
def getstr_with_echo(default = nil)
|
151
|
+
str = default || ''.dup
|
152
|
+
|
153
|
+
unless str.empty?
|
154
|
+
self << str
|
155
|
+
refresh
|
156
|
+
end
|
157
|
+
|
152
158
|
loop do
|
153
159
|
case (c = Curses.getch)
|
154
|
-
when 27
|
160
|
+
when 27, 3 # ESC, C-c
|
155
161
|
raise Interrupt
|
156
162
|
when 10, 13
|
157
163
|
break
|
164
|
+
when 127, 263 # delete
|
165
|
+
raise Interrupt if curx == 1
|
166
|
+
|
167
|
+
setpos cury, curx - 1
|
168
|
+
delch
|
169
|
+
refresh
|
170
|
+
str.chop!
|
158
171
|
else
|
172
|
+
Rfd.log "#{__method__}: #{c}"
|
159
173
|
self << c
|
160
174
|
refresh
|
161
175
|
str << c
|
@@ -164,10 +178,10 @@ module Rfd
|
|
164
178
|
str
|
165
179
|
end
|
166
180
|
|
167
|
-
def get_command(prompt: nil)
|
181
|
+
def get_command(prompt: nil, default: nil)
|
168
182
|
startx = prompt ? prompt.size : 1
|
169
183
|
setpos 0, startx
|
170
|
-
s = getstr_with_echo
|
184
|
+
s = getstr_with_echo default
|
171
185
|
"#{prompt[1..-1] if prompt}#{s.strip}"
|
172
186
|
end
|
173
187
|
|
data/lib/rfd.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'curses'
|
3
3
|
require 'fileutils'
|
4
|
+
require 'time'
|
4
5
|
require 'tmpdir'
|
5
6
|
require 'rubygems/package'
|
6
7
|
require 'zip'
|
@@ -8,9 +9,10 @@ require 'zip/filesystem'
|
|
8
9
|
require_relative 'rfd/commands'
|
9
10
|
require_relative 'rfd/item'
|
10
11
|
require_relative 'rfd/windows'
|
12
|
+
require_relative 'rfd/logging'
|
11
13
|
|
12
14
|
module Rfd
|
13
|
-
VERSION = Gem.loaded_specs['rfd'].version.to_s
|
15
|
+
VERSION = Gem.loaded_specs['rfd'] ? Gem.loaded_specs['rfd'].version.to_s : '0'
|
14
16
|
|
15
17
|
# :nodoc:
|
16
18
|
def self.init_curses
|
@@ -32,7 +34,9 @@ module Rfd
|
|
32
34
|
#
|
33
35
|
# ==== Parameters
|
34
36
|
# * +dir+ - The initial directory.
|
35
|
-
def self.start(dir = '.')
|
37
|
+
def self.start(dir = '.', log: nil)
|
38
|
+
Rfd.log_to log if log
|
39
|
+
|
36
40
|
init_curses
|
37
41
|
Rfd::Window.draw_borders
|
38
42
|
Curses.stdscr.noutrefresh
|
@@ -108,6 +112,7 @@ module Rfd
|
|
108
112
|
rescue StopIteration
|
109
113
|
raise
|
110
114
|
rescue => e
|
115
|
+
Rfd.logger.error e if Rfd.logger
|
111
116
|
command_line.show_error e.to_s
|
112
117
|
raise if ENV['DEBUG']
|
113
118
|
end
|
@@ -467,7 +472,9 @@ module Rfd
|
|
467
472
|
zip.instance_variable_get(:@entry_set) << Zip::Entry.new(current_zip, filename)
|
468
473
|
end
|
469
474
|
end
|
475
|
+
|
470
476
|
ls
|
477
|
+
move_cursor items.index {|i| i.name == filename}
|
471
478
|
end
|
472
479
|
|
473
480
|
# Create a symlink to the current file or directory.
|
@@ -476,6 +483,15 @@ module Rfd
|
|
476
483
|
ls
|
477
484
|
end
|
478
485
|
|
486
|
+
# Change the timestamp of the selected files and directories.
|
487
|
+
#
|
488
|
+
# ==== Parameters
|
489
|
+
# * +timestamp+ - A string that can be parsed with `Time.parse`. Note that this parameter is not compatible with UNIX `touch -t`.
|
490
|
+
def touch_t(timestamp)
|
491
|
+
FileUtils.touch selected_items, mtime: Time.parse(timestamp)
|
492
|
+
ls
|
493
|
+
end
|
494
|
+
|
479
495
|
# Yank selected file / directory names.
|
480
496
|
def yank
|
481
497
|
@yanked_items = selected_items
|
@@ -554,7 +570,7 @@ module Rfd
|
|
554
570
|
end
|
555
571
|
dest ||= File.join dest_dir, entry.full_name
|
556
572
|
if entry.directory?
|
557
|
-
FileUtils.mkdir_p dest, :
|
573
|
+
FileUtils.mkdir_p dest, mode: entry.header.mode
|
558
574
|
elsif entry.file?
|
559
575
|
FileUtils.mkdir_p dest_dir
|
560
576
|
File.open(dest, 'wb') {|f| f.print entry.read}
|
@@ -638,10 +654,11 @@ module Rfd
|
|
638
654
|
#
|
639
655
|
# ==== Parameters
|
640
656
|
# * +preset_command+ - A command that would be displayed at the command line before user input.
|
641
|
-
|
657
|
+
# * +default_argument+ - A default argument for the command.
|
658
|
+
def process_command_line(preset_command: nil, default_argument: nil)
|
642
659
|
prompt = preset_command ? ":#{preset_command} " : ':'
|
643
660
|
command_line.set_prompt prompt
|
644
|
-
cmd, *args = command_line.get_command(prompt: prompt).split(' ')
|
661
|
+
cmd, *args = command_line.get_command(prompt: prompt, default: default_argument).split(' ')
|
645
662
|
if cmd && !cmd.empty? && respond_to?(cmd)
|
646
663
|
ret = self.public_send cmd, *args
|
647
664
|
clear_command_line
|
@@ -673,8 +690,7 @@ module Rfd
|
|
673
690
|
command_line.refresh
|
674
691
|
while (c = Curses.getch)
|
675
692
|
next unless [?N, ?Y, ?n, ?y, 3, 27] .include? c # N, Y, n, y, ^c, esc
|
676
|
-
|
677
|
-
command_line.noutrefresh
|
693
|
+
clear_command_line
|
678
694
|
break (c == 'y') || (c == 'Y')
|
679
695
|
end
|
680
696
|
end
|
data/rfd.gemspec
CHANGED
@@ -5,22 +5,25 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "rfd"
|
8
|
-
spec.version = '0.
|
8
|
+
spec.version = '0.7.1'
|
9
9
|
spec.authors = ["Akira Matsuda"]
|
10
10
|
spec.email = ["ronnie@dio.jp"]
|
11
|
-
spec.description = 'Ruby
|
11
|
+
spec.description = 'A Ruby filer that runs on terminal'
|
12
12
|
spec.summary = 'Ruby on Files & Directories'
|
13
13
|
spec.homepage = 'https://github.com/amatsuda/rfd'
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files =
|
16
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
17
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
end
|
17
19
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
21
|
spec.require_paths = ["lib"]
|
20
22
|
|
21
23
|
spec.add_dependency 'curses', '>= 1.0.0'
|
22
24
|
spec.add_dependency 'rubyzip', '>= 1.0.0'
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency "rake"
|
25
|
-
spec.add_development_dependency 'rspec'
|
25
|
+
spec.add_development_dependency 'bundler'
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency 'rspec'
|
28
|
+
spec.add_development_dependency 'rspec-its'
|
26
29
|
end
|
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.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akira Matsuda
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -42,45 +42,59 @@ dependencies:
|
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-its
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
83
|
-
description: Ruby
|
96
|
+
version: '0'
|
97
|
+
description: A Ruby filer that runs on terminal
|
84
98
|
email:
|
85
99
|
- ronnie@dio.jp
|
86
100
|
executables:
|
@@ -97,31 +111,14 @@ files:
|
|
97
111
|
- lib/rfd.rb
|
98
112
|
- lib/rfd/commands.rb
|
99
113
|
- lib/rfd/item.rb
|
114
|
+
- lib/rfd/logging.rb
|
100
115
|
- lib/rfd/windows.rb
|
101
116
|
- rfd.gemspec
|
102
|
-
- spec/controller_spec.rb
|
103
|
-
- spec/spec_helper.rb
|
104
|
-
- spec/support/capture_helper.rb
|
105
|
-
- spec/testdir/.file1
|
106
|
-
- spec/testdir/.file2
|
107
|
-
- spec/testdir/.file3
|
108
|
-
- spec/testdir/.link1
|
109
|
-
- spec/testdir/dir1/.keep
|
110
|
-
- spec/testdir/dir2/.keep
|
111
|
-
- spec/testdir/dir3/.keep
|
112
|
-
- spec/testdir/dirlink1
|
113
|
-
- spec/testdir/file1
|
114
|
-
- spec/testdir/file2
|
115
|
-
- spec/testdir/file3
|
116
|
-
- spec/testdir/gz1.tar.gz
|
117
|
-
- spec/testdir/link1
|
118
|
-
- spec/testdir/link2
|
119
|
-
- spec/testdir/zip1.zip
|
120
117
|
homepage: https://github.com/amatsuda/rfd
|
121
118
|
licenses:
|
122
119
|
- MIT
|
123
120
|
metadata: {}
|
124
|
-
post_install_message:
|
121
|
+
post_install_message:
|
125
122
|
rdoc_options: []
|
126
123
|
require_paths:
|
127
124
|
- lib
|
@@ -136,26 +133,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
133
|
- !ruby/object:Gem::Version
|
137
134
|
version: '0'
|
138
135
|
requirements: []
|
139
|
-
rubygems_version: 3.0.
|
140
|
-
signing_key:
|
136
|
+
rubygems_version: 3.5.0.dev
|
137
|
+
signing_key:
|
141
138
|
specification_version: 4
|
142
139
|
summary: Ruby on Files & Directories
|
143
|
-
test_files:
|
144
|
-
- spec/controller_spec.rb
|
145
|
-
- spec/spec_helper.rb
|
146
|
-
- spec/support/capture_helper.rb
|
147
|
-
- spec/testdir/.file1
|
148
|
-
- spec/testdir/.file2
|
149
|
-
- spec/testdir/.file3
|
150
|
-
- spec/testdir/.link1
|
151
|
-
- spec/testdir/dir1/.keep
|
152
|
-
- spec/testdir/dir2/.keep
|
153
|
-
- spec/testdir/dir3/.keep
|
154
|
-
- spec/testdir/dirlink1
|
155
|
-
- spec/testdir/file1
|
156
|
-
- spec/testdir/file2
|
157
|
-
- spec/testdir/file3
|
158
|
-
- spec/testdir/gz1.tar.gz
|
159
|
-
- spec/testdir/link1
|
160
|
-
- spec/testdir/link2
|
161
|
-
- spec/testdir/zip1.zip
|
140
|
+
test_files: []
|
data/spec/controller_spec.rb
DELETED
@@ -1,439 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
|
-
require 'rfd'
|
4
|
-
|
5
|
-
describe Rfd::Controller do
|
6
|
-
include CaptureHelper
|
7
|
-
|
8
|
-
around do |example|
|
9
|
-
@stdout = capture(:stdout) do
|
10
|
-
FileUtils.cp_r File.join(__dir__, 'testdir'), tmpdir
|
11
|
-
@rfd = Rfd.start tmpdir
|
12
|
-
def (@rfd.main).maxy
|
13
|
-
3
|
14
|
-
end
|
15
|
-
|
16
|
-
example.run
|
17
|
-
|
18
|
-
FileUtils.rm_r tmpdir
|
19
|
-
Dir.chdir __dir__
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
after :all do
|
24
|
-
Curses.close_screen
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:tmpdir) { File.join __dir__, 'tmpdir' }
|
28
|
-
let!(:controller) { @rfd }
|
29
|
-
subject { controller }
|
30
|
-
let(:items) { controller.items }
|
31
|
-
|
32
|
-
describe '#spawn_panes' do
|
33
|
-
before { controller.spawn_panes 3 }
|
34
|
-
|
35
|
-
subject { controller.main.instance_variable_get :@number_of_panes }
|
36
|
-
it { should == 3 }
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '#current_item' do
|
40
|
-
before do
|
41
|
-
controller.instance_variable_set :@current_row, 3
|
42
|
-
end
|
43
|
-
its(:current_item) { should == items[3] }
|
44
|
-
end
|
45
|
-
|
46
|
-
describe '#marked_items' do
|
47
|
-
before do
|
48
|
-
items[2].toggle_mark
|
49
|
-
items[3].toggle_mark
|
50
|
-
end
|
51
|
-
its(:marked_items) { should == [items[2], items[3]] }
|
52
|
-
end
|
53
|
-
|
54
|
-
describe '#selected_items' do
|
55
|
-
context 'When no items were marked' do
|
56
|
-
context 'When the cursor is on . or ..' do
|
57
|
-
its(:selected_items) { should be_empty }
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'When the cursor is not on . nor ..' do
|
61
|
-
before do
|
62
|
-
controller.instance_variable_set :@current_row, 5
|
63
|
-
end
|
64
|
-
its(:selected_items) { should == [items[5]] }
|
65
|
-
end
|
66
|
-
end
|
67
|
-
context 'When items were marked' do
|
68
|
-
before do
|
69
|
-
items[2].toggle_mark
|
70
|
-
items[4].toggle_mark
|
71
|
-
end
|
72
|
-
its(:selected_items) { should == [items[2], items[4]] }
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe '#move_cursor' do
|
77
|
-
context 'When moving to nil' do
|
78
|
-
before do
|
79
|
-
controller.move_cursor nil
|
80
|
-
end
|
81
|
-
its(:current_row) { should == 0 }
|
82
|
-
end
|
83
|
-
context 'When moving to a certain row' do
|
84
|
-
before do
|
85
|
-
controller.move_cursor 2
|
86
|
-
end
|
87
|
-
its(:current_row) { should == 2 }
|
88
|
-
|
89
|
-
context 'When moving to the second pane' do
|
90
|
-
before do
|
91
|
-
controller.move_cursor 5
|
92
|
-
end
|
93
|
-
subject { controller.main.instance_variable_get :@current_index }
|
94
|
-
it { should == 1 }
|
95
|
-
end
|
96
|
-
|
97
|
-
context 'When moving to the second page' do
|
98
|
-
before do
|
99
|
-
controller.move_cursor 7
|
100
|
-
end
|
101
|
-
its(:current_page) { should == 1 }
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
describe '#cd' do
|
107
|
-
before do
|
108
|
-
controller.cd 'dir1'
|
109
|
-
end
|
110
|
-
its('current_dir.path') { should == File.join(tmpdir, 'dir1') }
|
111
|
-
|
112
|
-
describe '#popd' do
|
113
|
-
before do
|
114
|
-
controller.popd
|
115
|
-
end
|
116
|
-
its('current_dir.path') { should == tmpdir }
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe '#ls' do
|
121
|
-
before do
|
122
|
-
controller.instance_variable_set :@items, []
|
123
|
-
controller.ls
|
124
|
-
end
|
125
|
-
its(:items) { should_not be_empty }
|
126
|
-
end
|
127
|
-
|
128
|
-
describe '#sort' do
|
129
|
-
let(:item) do
|
130
|
-
Dir.mkdir File.join(tmpdir, '.a')
|
131
|
-
stat = File.lstat File.join(tmpdir, '.a')
|
132
|
-
Rfd::Item.new dir: tmpdir, name: '.a', stat: stat, window_width: 100
|
133
|
-
end
|
134
|
-
before do
|
135
|
-
controller.items << item
|
136
|
-
controller.sort
|
137
|
-
end
|
138
|
-
subject { item }
|
139
|
-
its(:index) { should == 2 } # . .. then next
|
140
|
-
end
|
141
|
-
|
142
|
-
describe '#chmod' do
|
143
|
-
let(:item) { controller.items.detect {|i| !i.directory?} }
|
144
|
-
|
145
|
-
context 'With an octet string' do
|
146
|
-
before do
|
147
|
-
item.toggle_mark
|
148
|
-
controller.chmod '666'
|
149
|
-
end
|
150
|
-
subject { controller.items.detect {|i| !i.directory?} }
|
151
|
-
its(:mode) { should == '-rw-rw-rw-' }
|
152
|
-
end
|
153
|
-
|
154
|
-
context 'With a decimal string' do
|
155
|
-
before do
|
156
|
-
item.toggle_mark
|
157
|
-
controller.chmod '0666'
|
158
|
-
end
|
159
|
-
subject { controller.items.detect {|i| !i.directory?} }
|
160
|
-
its(:mode) { should == '-rw-rw-rw-' }
|
161
|
-
end
|
162
|
-
|
163
|
-
context 'With a non-numeric string' do
|
164
|
-
before do
|
165
|
-
item.toggle_mark
|
166
|
-
controller.chmod 'a+w'
|
167
|
-
end
|
168
|
-
subject { controller.items.detect {|i| !i.directory?} }
|
169
|
-
its(:mode) { should == '-rw-rw-rw-' }
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe '#chown' do
|
174
|
-
let(:item) { controller.items.detect {|i| !i.directory?} }
|
175
|
-
subject { item }
|
176
|
-
|
177
|
-
context 'With user name only' do
|
178
|
-
before do
|
179
|
-
expect(FileUtils).to receive(:chown).with('alice', nil, Array(item.path))
|
180
|
-
item.toggle_mark
|
181
|
-
end
|
182
|
-
specify { controller.chown 'alice' }
|
183
|
-
end
|
184
|
-
|
185
|
-
context 'With group name only' do
|
186
|
-
before do
|
187
|
-
expect(FileUtils).to receive(:chown).with(nil, 'admin', Array(item.path))
|
188
|
-
item.toggle_mark
|
189
|
-
end
|
190
|
-
specify { controller.chown ':admin' }
|
191
|
-
end
|
192
|
-
|
193
|
-
context 'With both user name and group name' do
|
194
|
-
before do
|
195
|
-
expect(FileUtils).to receive(:chown).with('nobody', 'nobody', Array(item.path))
|
196
|
-
item.toggle_mark
|
197
|
-
end
|
198
|
-
specify { controller.chown 'nobody:nobody' }
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
describe '#find' do
|
203
|
-
before do
|
204
|
-
controller.find 'd'
|
205
|
-
end
|
206
|
-
its('current_item.name') { should start_with('d') }
|
207
|
-
end
|
208
|
-
|
209
|
-
describe '#find_reverse' do
|
210
|
-
before do
|
211
|
-
controller.find_reverse 'f'
|
212
|
-
end
|
213
|
-
its('current_item.name') { should == 'file3' }
|
214
|
-
end
|
215
|
-
|
216
|
-
describe '#grep' do
|
217
|
-
before do
|
218
|
-
controller.grep 'dir'
|
219
|
-
end
|
220
|
-
subject { controller.items[2..-1] }
|
221
|
-
its(:size) { should be > 2 }
|
222
|
-
it "all items' name should include 'dir'" do
|
223
|
-
subject.all? {|i| i.name.should include('dir')}
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
describe '#cp' do
|
228
|
-
before do
|
229
|
-
controller.find 'file1'
|
230
|
-
controller.cp 'file4'
|
231
|
-
end
|
232
|
-
it 'should be the same file as the copy source file' do
|
233
|
-
File.read(File.join(tmpdir, 'file1')).should == File.read(File.join(tmpdir, 'file4'))
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
describe '#mv' do
|
238
|
-
before do
|
239
|
-
controller.find 'file3'
|
240
|
-
controller.mv 'dir2'
|
241
|
-
end
|
242
|
-
subject { File }
|
243
|
-
it { should be_exist File.join(tmpdir, 'dir2/file3') }
|
244
|
-
end
|
245
|
-
|
246
|
-
describe '#rename' do
|
247
|
-
before do
|
248
|
-
controller.find '.file2'
|
249
|
-
controller.toggle_mark
|
250
|
-
controller.find 'file3'
|
251
|
-
controller.toggle_mark
|
252
|
-
controller.rename 'fi/faaai'
|
253
|
-
end
|
254
|
-
subject { File }
|
255
|
-
it { should be_exist File.join(tmpdir, '.faaaile2') }
|
256
|
-
it { should be_exist File.join(tmpdir, 'faaaile3') }
|
257
|
-
end
|
258
|
-
|
259
|
-
describe '#trash' do
|
260
|
-
before do
|
261
|
-
controller.find 'file3'
|
262
|
-
controller.toggle_mark
|
263
|
-
controller.trash
|
264
|
-
end
|
265
|
-
it 'should be properly deleted from the current directory' do
|
266
|
-
controller.items.should be_none {|i| i.name == 'file3'}
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
describe '#delete' do
|
271
|
-
before do
|
272
|
-
controller.find 'file3'
|
273
|
-
controller.toggle_mark
|
274
|
-
controller.find 'dir2'
|
275
|
-
controller.toggle_mark
|
276
|
-
controller.delete
|
277
|
-
end
|
278
|
-
it 'should be properly deleted from the current directory' do
|
279
|
-
controller.items.should be_none {|i| i.name == 'file3'}
|
280
|
-
controller.items.should be_none {|i| i.name == 'dir2'}
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
describe '#mkdir' do
|
285
|
-
before do
|
286
|
-
controller.mkdir 'aho'
|
287
|
-
end
|
288
|
-
subject { Dir }
|
289
|
-
it { should be_exist File.join(tmpdir, 'aho') }
|
290
|
-
end
|
291
|
-
|
292
|
-
describe '#touch' do
|
293
|
-
before do
|
294
|
-
controller.touch 'fuga'
|
295
|
-
end
|
296
|
-
subject { File }
|
297
|
-
it { should be_exist File.join(tmpdir, 'fuga') }
|
298
|
-
end
|
299
|
-
|
300
|
-
describe '#symlink' do
|
301
|
-
before do
|
302
|
-
controller.find 'dir1'
|
303
|
-
controller.symlink 'aaa'
|
304
|
-
end
|
305
|
-
subject { File }
|
306
|
-
it { should be_symlink File.join(tmpdir, 'aaa') }
|
307
|
-
end
|
308
|
-
|
309
|
-
describe '#yank' do
|
310
|
-
before do
|
311
|
-
controller.find '.file1'
|
312
|
-
controller.toggle_mark
|
313
|
-
controller.find 'dir3'
|
314
|
-
controller.toggle_mark
|
315
|
-
controller.yank
|
316
|
-
end
|
317
|
-
it 'should be yanked' do
|
318
|
-
controller.instance_variable_get(:@yanked_items).map(&:name).should =~ %w(.file1 dir3)
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
describe '#paste' do
|
323
|
-
before do
|
324
|
-
controller.find '.file1'
|
325
|
-
controller.toggle_mark
|
326
|
-
controller.find 'dir3'
|
327
|
-
controller.toggle_mark
|
328
|
-
controller.yank
|
329
|
-
end
|
330
|
-
context 'when the cursor is on a directory' do
|
331
|
-
before do
|
332
|
-
controller.find 'dir1'
|
333
|
-
controller.paste
|
334
|
-
end
|
335
|
-
subject { File }
|
336
|
-
it { should be_exist File.join(tmpdir, 'dir1', '.file1') }
|
337
|
-
it { should be_exist File.join(tmpdir, 'dir1', 'dir3') }
|
338
|
-
end
|
339
|
-
context 'when the cursor is on a file' do
|
340
|
-
before do
|
341
|
-
controller.find 'file2'
|
342
|
-
controller.paste
|
343
|
-
end
|
344
|
-
subject { File }
|
345
|
-
it { should be_exist File.join(tmpdir, '.file1_2') }
|
346
|
-
it { should be_exist File.join(tmpdir, 'dir3_2') }
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
if RbConfig::CONFIG['host_os'] =~ /darwin/
|
351
|
-
describe '#pbcopy' do
|
352
|
-
before do
|
353
|
-
controller.find '.file1'
|
354
|
-
controller.toggle_mark
|
355
|
-
controller.find 'dir3'
|
356
|
-
controller.toggle_mark
|
357
|
-
controller.clipboard
|
358
|
-
end
|
359
|
-
it 'copies the selected paths into clipboard' do
|
360
|
-
`pbpaste`.should == "#{File.join(tmpdir, 'dir3')} #{File.join(tmpdir, '.file1')}"
|
361
|
-
end
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
describe '#zip' do
|
366
|
-
before do
|
367
|
-
controller.find 'dir1'
|
368
|
-
controller.zip 'archive1'
|
369
|
-
end
|
370
|
-
subject { File }
|
371
|
-
it { should be_exist File.join(tmpdir, 'archive1.zip') }
|
372
|
-
end
|
373
|
-
|
374
|
-
describe '#unarchive' do
|
375
|
-
before do
|
376
|
-
controller.find 'zip1'
|
377
|
-
controller.toggle_mark
|
378
|
-
controller.find 'gz1'
|
379
|
-
controller.toggle_mark
|
380
|
-
controller.unarchive
|
381
|
-
end
|
382
|
-
subject { File }
|
383
|
-
it { should be_exist File.join(tmpdir, 'zip1/zip_content1') }
|
384
|
-
it { should be_exist File.join(tmpdir, 'zip1/zip_content_dir1/zip_content1_1') }
|
385
|
-
it { should be_exist File.join(tmpdir, 'gz1/gz_content1') }
|
386
|
-
it { should be_exist File.join(tmpdir, 'gz1/gz_content_dir1/gz_content1_1') }
|
387
|
-
end
|
388
|
-
|
389
|
-
describe '#first_page? and #last_page?' do
|
390
|
-
context 'When on the first page' do
|
391
|
-
it { should be_first_page }
|
392
|
-
it { should_not be_last_page }
|
393
|
-
end
|
394
|
-
context 'When on the first page' do
|
395
|
-
before do
|
396
|
-
controller.k
|
397
|
-
end
|
398
|
-
it { should_not be_first_page }
|
399
|
-
it { should be_last_page }
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
describe '#total_pages' do
|
404
|
-
its(:total_pages) { should == 3 } # 15 / (3 * 2) + 1
|
405
|
-
end
|
406
|
-
|
407
|
-
describe '#switch_page' do
|
408
|
-
before do
|
409
|
-
controller.switch_page 2
|
410
|
-
end
|
411
|
-
its(:current_page) { should == 2 }
|
412
|
-
end
|
413
|
-
|
414
|
-
describe '#toggle_mark' do
|
415
|
-
before do
|
416
|
-
controller.move_cursor 10
|
417
|
-
controller.toggle_mark
|
418
|
-
end
|
419
|
-
subject { items[10] }
|
420
|
-
it { should be_marked }
|
421
|
-
end
|
422
|
-
|
423
|
-
describe 'times' do
|
424
|
-
subject { controller.times }
|
425
|
-
context 'before accepting 0-9' do
|
426
|
-
it { should == 1 }
|
427
|
-
end
|
428
|
-
context 'When 0-9 were typed' do
|
429
|
-
before do
|
430
|
-
controller.public_send '3'
|
431
|
-
controller.public_send '7'
|
432
|
-
end
|
433
|
-
after do
|
434
|
-
controller.instance_variable_set :@times, nil
|
435
|
-
end
|
436
|
-
it { should == 37 }
|
437
|
-
end
|
438
|
-
end
|
439
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'tempfile'
|
3
|
-
|
4
|
-
# copied from ActiveSupport 4
|
5
|
-
module CaptureHelper
|
6
|
-
def capture(stream)
|
7
|
-
stream = stream.to_s
|
8
|
-
captured_stream = Tempfile.new(stream)
|
9
|
-
stream_io = eval("$#{stream}")
|
10
|
-
origin_stream = stream_io.dup
|
11
|
-
stream_io.reopen(captured_stream)
|
12
|
-
|
13
|
-
yield
|
14
|
-
|
15
|
-
stream_io.rewind
|
16
|
-
return captured_stream.read
|
17
|
-
ensure
|
18
|
-
captured_stream.close
|
19
|
-
captured_stream.unlink
|
20
|
-
stream_io.reopen(origin_stream)
|
21
|
-
end
|
22
|
-
end
|
data/spec/testdir/.file1
DELETED
File without changes
|
data/spec/testdir/.file2
DELETED
File without changes
|
data/spec/testdir/.file3
DELETED
File without changes
|
data/spec/testdir/.link1
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
.file1
|
data/spec/testdir/dir1/.keep
DELETED
File without changes
|
data/spec/testdir/dir2/.keep
DELETED
File without changes
|
data/spec/testdir/dir3/.keep
DELETED
File without changes
|
data/spec/testdir/dirlink1
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
spec/testdir/dir1
|
data/spec/testdir/file1
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
file1
|
data/spec/testdir/file2
DELETED
File without changes
|
data/spec/testdir/file3
DELETED
File without changes
|
data/spec/testdir/gz1.tar.gz
DELETED
Binary file
|
data/spec/testdir/link1
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
spec/testdir/file1
|
data/spec/testdir/link2
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
spec/testdir/file2
|
data/spec/testdir/zip1.zip
DELETED
Binary file
|