navtor 0.0.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 +7 -0
- data/README.md +1 -0
- data/bin/navtor +198 -0
- data/lib/navtor/version.rb +4 -0
- data/navtor.gemspec +26 -0
- metadata +77 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8edaf937f4e8a82b52a7d476376a68b63db29b09
|
4
|
+
data.tar.gz: f414b0b417b9d4415aa29241400725d1f6746768
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c69364c7c54c4899c09d570b0962bcb32912b97f0b51b0f3e2fcef6cde0041a9225f269b26bb0194f2abc262cbd94f34bd1a0b81793db5571d7d04f928b131ac
|
7
|
+
data.tar.gz: 0bb734bc3d44c9b581801e8b70fe31b5c7378f7d72ce12cbe292581e88baa59c25a62dda806338eb04cf3179369a23be88a9b27fc6916c8bc9269735a0e9c64d
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rfm is a Ruby-based clone of [fff](https://github.com/dylanaraps/fff/).
|
data/bin/navtor
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is a clone of fff written in Bash
|
3
|
+
# Things learned:
|
4
|
+
# * Need to remember to init_color
|
5
|
+
# * `Curses.init_pair(1, -1, -1)` can be used to get default colors
|
6
|
+
# * `stdscr.scrollok(false)` need to be used to avoid new line created at the bottom
|
7
|
+
require 'curses'
|
8
|
+
|
9
|
+
class FileManager
|
10
|
+
attr_accessor :entries, :current_pos
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@entries = []
|
14
|
+
@current_pos = 0
|
15
|
+
@ui = UI.new(self)
|
16
|
+
ls
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
@ui.run
|
21
|
+
end
|
22
|
+
|
23
|
+
def ls
|
24
|
+
@entries = (Dir.entries('.') - ['.', '..']).sort
|
25
|
+
@entries.each.with_index do |entry, index|
|
26
|
+
if File.directory?(entry)
|
27
|
+
@entries[index] = "[#{entry}]"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
@ui.calculate_lines
|
31
|
+
end
|
32
|
+
|
33
|
+
def current_entry
|
34
|
+
@entries[@current_pos]
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_parent_dir
|
38
|
+
Dir.chdir('..')
|
39
|
+
ls
|
40
|
+
@ui.reset
|
41
|
+
end
|
42
|
+
|
43
|
+
def open_current
|
44
|
+
return if current_entry.nil?
|
45
|
+
is_file = current_entry.match('\[(.+)\]').nil?
|
46
|
+
if !is_file
|
47
|
+
Dir.chdir(current_entry.match('\[(.+)\]')[1])
|
48
|
+
ls
|
49
|
+
@ui.reset
|
50
|
+
else
|
51
|
+
@ui.close_screen
|
52
|
+
#Curses.def_prog_mode
|
53
|
+
system("vim #{Dir.pwd}/#{current_entry}")
|
54
|
+
#Curses.reset_prog_mode
|
55
|
+
@ui.init_screen
|
56
|
+
@ui.refresh
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class UI
|
62
|
+
attr_accessor :start_line, :end_line
|
63
|
+
def initialize(fm)
|
64
|
+
@fm = fm
|
65
|
+
Curses.noecho
|
66
|
+
Curses.nonl
|
67
|
+
Curses.stdscr.keypad(true)
|
68
|
+
Curses.raw
|
69
|
+
Curses.stdscr.nodelay = 1
|
70
|
+
self.init_screen
|
71
|
+
@lines = Curses.lines
|
72
|
+
@cols = Curses.cols
|
73
|
+
@offset = 0 # Offset within current directory's entries
|
74
|
+
|
75
|
+
@start_line = 0 # Start line of file list on screen, should be 0
|
76
|
+
@end_line = @lines - 1 # End line of file list on screen
|
77
|
+
@current_line = 0
|
78
|
+
|
79
|
+
@input = nil
|
80
|
+
stdscr.timeout = -1
|
81
|
+
stdscr.scrollok(false) # Avoid scrolling
|
82
|
+
stdscr.idlok(true)
|
83
|
+
end
|
84
|
+
|
85
|
+
def init_screen
|
86
|
+
Curses.init_screen
|
87
|
+
Curses.start_color
|
88
|
+
Curses.use_default_colors
|
89
|
+
Curses.init_pair(1, -1, -1) # Get defautl colors
|
90
|
+
Curses.init_pair(2, Curses::COLOR_GREEN, -1)
|
91
|
+
Curses.curs_set(0)
|
92
|
+
end
|
93
|
+
|
94
|
+
def close_screen
|
95
|
+
Curses.close_screen
|
96
|
+
end
|
97
|
+
|
98
|
+
def calculate_lines
|
99
|
+
@end_line = [@lines - 2, @fm.entries.size-1].min
|
100
|
+
end
|
101
|
+
|
102
|
+
def page_size
|
103
|
+
@end_line - @start_line
|
104
|
+
end
|
105
|
+
|
106
|
+
def stdscr
|
107
|
+
Curses.stdscr
|
108
|
+
end
|
109
|
+
|
110
|
+
def reset
|
111
|
+
@current_line = 0
|
112
|
+
@offset = 0
|
113
|
+
end
|
114
|
+
|
115
|
+
def refresh
|
116
|
+
Curses.clear
|
117
|
+
stdscr.refresh
|
118
|
+
end
|
119
|
+
|
120
|
+
def print_entries
|
121
|
+
visible_entries = @fm.entries[@offset + @start_line, @end_line - @start_line + 1]
|
122
|
+
visible_entries.each.with_index do |line, index|
|
123
|
+
if index == @current_line
|
124
|
+
@fm.current_pos = index + @offset
|
125
|
+
stdscr.attron(Curses.color_pair(1) | Curses::A_REVERSE) {
|
126
|
+
stdscr.addstr("#{line}")
|
127
|
+
}
|
128
|
+
else
|
129
|
+
stdscr.addstr("#{line}")
|
130
|
+
end
|
131
|
+
stdscr.setpos(stdscr.cury + 1, 0)
|
132
|
+
end
|
133
|
+
stdscr.addstr("(empty)") if visible_entries.empty?
|
134
|
+
stdscr.refresh
|
135
|
+
end
|
136
|
+
|
137
|
+
def status_line(str="", clear = true)
|
138
|
+
curx, cury = stdscr.curx, stdscr.cury
|
139
|
+
str = "#{Dir.pwd} (#{@fm.current_pos + 1}/#{@fm.entries.size}) off=#{@offset} cur=#{@current_line} end=#{@end_line} w=#{@cols} h=#{@lines} input=#{@input}" + str
|
140
|
+
if clear
|
141
|
+
stdscr.setpos(@lines - 1, 0)
|
142
|
+
stdscr.addstr(' ' * @cols)
|
143
|
+
end
|
144
|
+
stdscr.setpos(@lines - 1, 0)
|
145
|
+
stdscr.attron(Curses.color_pair(2) | Curses::A_NORMAL) {
|
146
|
+
stdscr.addstr(str)
|
147
|
+
}
|
148
|
+
stdscr.setpos(cury, curx)
|
149
|
+
stdscr.refresh
|
150
|
+
end
|
151
|
+
|
152
|
+
def run
|
153
|
+
refresh
|
154
|
+
print_entries
|
155
|
+
status_line
|
156
|
+
until (@input = stdscr.getch) == 'q'
|
157
|
+
refresh
|
158
|
+
handle(@input)
|
159
|
+
print_entries
|
160
|
+
status_line
|
161
|
+
end
|
162
|
+
ensure
|
163
|
+
self.exit
|
164
|
+
end
|
165
|
+
|
166
|
+
def handle(input)
|
167
|
+
if input == 'j' || input == 258
|
168
|
+
@current_line = (@current_line == @end_line) ? @current_line : @current_line + 1
|
169
|
+
@offset += 1 if @current_line == @end_line && @offset + page_size < @fm.entries.size - 1
|
170
|
+
elsif input == 'k' || input == 259
|
171
|
+
@current_line = (@current_line == @start_line) ? @current_line : @current_line - 1
|
172
|
+
@offset -=1 if @current_line == @start_line && @offset > 0
|
173
|
+
elsif input == 'g'
|
174
|
+
@offset = 0
|
175
|
+
@current_line = 0
|
176
|
+
elsif input == 'G'
|
177
|
+
@offset = @fm.entries.size - 1 - page_size
|
178
|
+
@current_line = @end_line
|
179
|
+
elsif input == 'h' || input == 260
|
180
|
+
@offset = 0
|
181
|
+
@fm.to_parent_dir
|
182
|
+
elsif input == 'l' || input == 261
|
183
|
+
@fm.open_current
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def exit
|
188
|
+
Curses.clear
|
189
|
+
Curses.close_screen
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def main
|
194
|
+
fm = FileManager.new
|
195
|
+
fm.run
|
196
|
+
end
|
197
|
+
|
198
|
+
main
|
data/navtor.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path('../lib', __FILE__)
|
2
|
+
require 'navtor/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = 'navtor'
|
6
|
+
spec.version = Navtor::VERSION
|
7
|
+
spec.date = Navtor::DATE
|
8
|
+
spec.description = 'Vi-like file manager'
|
9
|
+
spec.summary = spec.description
|
10
|
+
|
11
|
+
spec.authors = ['Thanh Dinh Khac']
|
12
|
+
spec.email = 'thanhdk@gmail.com'
|
13
|
+
|
14
|
+
spec.homepage = 'http://rubygems.org/gems/navtor'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = %w[navtor.gemspec] + Dir['*.md', 'bin/*', 'lib/*', 'lib/**/*.rb']
|
18
|
+
spec.require_paths << 'lib'
|
19
|
+
spec.executables = ['navtor']
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 2.0'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.0"
|
24
|
+
|
25
|
+
spec.add_dependency 'curses', '~> 1.2'
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: navtor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thanh Dinh Khac
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-10-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: curses
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.2'
|
41
|
+
description: Vi-like file manager
|
42
|
+
email: thanhdk@gmail.com
|
43
|
+
executables:
|
44
|
+
- navtor
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- README.md
|
49
|
+
- bin/navtor
|
50
|
+
- lib/navtor/version.rb
|
51
|
+
- navtor.gemspec
|
52
|
+
homepage: http://rubygems.org/gems/navtor
|
53
|
+
licenses:
|
54
|
+
- MIT
|
55
|
+
metadata: {}
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '2.0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 2.5.1
|
74
|
+
signing_key:
|
75
|
+
specification_version: 4
|
76
|
+
summary: Vi-like file manager
|
77
|
+
test_files: []
|