Class: Rfd::Controller
Instance Attribute Summary collapse
-
#command_line ⇒ Object
readonly
Returns the value of attribute command_line.
-
#current_dir ⇒ Object
readonly
Returns the value of attribute current_dir.
-
#current_page ⇒ Object
readonly
Returns the value of attribute current_page.
-
#current_row ⇒ Object
readonly
Returns the value of attribute current_row.
-
#current_zip ⇒ Object
readonly
Returns the value of attribute current_zip.
-
#displayed_items ⇒ Object
readonly
Returns the value of attribute displayed_items.
-
#header_l ⇒ Object
readonly
Returns the value of attribute header_l.
-
#header_r ⇒ Object
readonly
Returns the value of attribute header_r.
-
#items ⇒ Object
readonly
Returns the value of attribute items.
-
#main ⇒ Object
readonly
Returns the value of attribute main.
Instance Method Summary collapse
-
#ask(prompt = '(y/n)') ⇒ Object
Let the user answer y or n.
-
#cd(dir, pushd: true) ⇒ Object
Change the current directory.
- #cd_into_zip(zipfile) ⇒ Object
-
#chmod(mode = nil) ⇒ Object
Change the file permission of the selected files and directories.
-
#chown(user_and_group) ⇒ Object
Change the file owner of the selected files and directories.
-
#clipboard ⇒ Object
Copy selected files and directories’ path into clipboard on OSX.
-
#cp(dest) ⇒ Object
Copy selected files and directories to the destination.
-
#current_item ⇒ Object
The file or directory on which the cursor is on.
-
#delete ⇒ Object
Delete selected files and directories.
-
#draw_items ⇒ Object
Update the main window with the loaded files and directories.
-
#draw_marked_items ⇒ Object
Update the header information concerning currently marked files or directories.
-
#draw_total_items ⇒ Object
Update the header information concerning total files and directories in the current directory.
-
#edit ⇒ Object
Open current file or directory with the editor.
-
#fetch_items_from_filesystem_or_zip ⇒ Object
Fetch files from current directory or current .zip file.
-
#find(str) ⇒ Object
Focus at the first file or directory of which name starts with the given String.
-
#find_reverse(str) ⇒ Object
Focus at the last file or directory of which name starts with the given String.
-
#first_page? ⇒ Boolean
Current page is the first page?.
-
#get_char ⇒ Object
Get a char as a String from user input.
-
#grep(pattern = '.*') ⇒ Object
Search files and directories from the current directory, and update the screen.
-
#initialize ⇒ Controller
constructor
:nodoc:.
-
#last_page? ⇒ Boolean
Do we have more pages?.
-
#ls ⇒ Object
Fetch files from current directory.
-
#marked_items ⇒ Object
-
marked files and directories.
-
-
#max_items ⇒ Object
Number of files or directories that the current main window can show in a page.
-
#maxx ⇒ Object
Width of the currently active pane.
-
#maxy ⇒ Object
Height of the currently active pane.
-
#mkdir(dir) ⇒ Object
Create a new directory.
-
#move_cursor(row = nil) ⇒ Object
Move the cursor to specified row.
- #move_cursor_by_click(y: nil, x: nil) ⇒ Object
-
#mv(dest) ⇒ Object
Move selected files and directories to the destination.
-
#popd ⇒ Object
cd to the previous directory.
-
#process_command_line(preset_command: nil) ⇒ Object
Accept user input, and directly execute it as a Ruby method call to the controller.
-
#process_shell_command ⇒ Object
Accept user input, and directly execute it in an external shell.
-
#rename(pattern) ⇒ Object
Rename selected files and directories.
-
#run ⇒ Object
The main loop.
-
#selected_items ⇒ Object
Marked files and directories or Array(the current file or directory).
-
#sort(direction = nil) ⇒ Object
Sort the whole files and directories in the current directory, then refresh the screen.
-
#sort_items_according_to_current_direction ⇒ Object
Sort the loaded files and directories in already given sort order.
-
#spawn_panes(num) ⇒ Object
Change the number of columns in the main window.
-
#switch_page(page) ⇒ Object
Move to the given page number.
-
#symlink(name) ⇒ Object
Create a symlink to the current file or directory.
-
#times ⇒ Object
Number of times to repeat the next command.
-
#toggle_mark ⇒ Object
Swktch on / off marking on the current file or directory.
-
#total_pages ⇒ Object
Number of pages in the current directory.
-
#touch(filename) ⇒ Object
Create a new empty file.
-
#trash ⇒ Object
Soft delete selected files and directories.
-
#unarchive ⇒ Object
Unarchive .zip and .tar.gz files within selected files and directories into current_directory.
-
#view ⇒ Object
Open current file or directory with the viewer.
-
#zip(zipfile_name) ⇒ Object
Archive selected files and directories into a .zip file.
Methods included from Commands
#-, #/, #C, #D, #F, #G, #H, #K, #L, #M, #O, #S, #a, #c, #click, #ctrl_a, #ctrl_b, #ctrl_f, #ctrl_l, #ctrl_n, #ctrl_p, #ctrl_w, #d, #del, #double_click, #e, #enter, #f, #g, #h, #j, #k, #l, #m, #n, #o, #q, #r, #s, #space, #t, #u, #v, #w, #z
Constructor Details
#initialize ⇒ Controller
:nodoc:
51 52 53 54 55 56 57 |
# File 'lib/rfd.rb', line 51 def initialize @main = MainWindow.new @header_l = HeaderLeftWindow.new @header_r = HeaderRightWindow.new @command_line = CommandLineWindow.new @direction, @dir_history, @last_command, @times = nil, [], nil, nil end |
Instance Attribute Details
#command_line ⇒ Object (readonly)
Returns the value of attribute command_line.
48 49 50 |
# File 'lib/rfd.rb', line 48 def command_line @command_line end |
#current_dir ⇒ Object (readonly)
Returns the value of attribute current_dir.
48 49 50 |
# File 'lib/rfd.rb', line 48 def current_dir @current_dir end |
#current_page ⇒ Object (readonly)
Returns the value of attribute current_page.
48 49 50 |
# File 'lib/rfd.rb', line 48 def current_page @current_page end |
#current_row ⇒ Object (readonly)
Returns the value of attribute current_row.
48 49 50 |
# File 'lib/rfd.rb', line 48 def current_row @current_row end |
#current_zip ⇒ Object (readonly)
Returns the value of attribute current_zip.
48 49 50 |
# File 'lib/rfd.rb', line 48 def current_zip @current_zip end |
#displayed_items ⇒ Object (readonly)
Returns the value of attribute displayed_items.
48 49 50 |
# File 'lib/rfd.rb', line 48 def displayed_items @displayed_items end |
#header_l ⇒ Object (readonly)
Returns the value of attribute header_l.
48 49 50 |
# File 'lib/rfd.rb', line 48 def header_l @header_l end |
#header_r ⇒ Object (readonly)
Returns the value of attribute header_r.
48 49 50 |
# File 'lib/rfd.rb', line 48 def header_r @header_r end |
#items ⇒ Object (readonly)
Returns the value of attribute items.
48 49 50 |
# File 'lib/rfd.rb', line 48 def items @items end |
#main ⇒ Object (readonly)
Returns the value of attribute main.
48 49 50 |
# File 'lib/rfd.rb', line 48 def main @main end |
Instance Method Details
#ask(prompt = '(y/n)') ⇒ Object
Let the user answer y or n.
Parameters
-
prompt- Prompt message
645 646 647 648 649 650 651 652 653 654 |
# File 'lib/rfd.rb', line 645 def ask(prompt = '(y/n)') command_line.set_prompt prompt command_line.wrefresh while (c = Curses.getch) next unless [78, 89, 110, 121, 3, 27] .include? c # N, Y, n, y, ^c, esc command_line.wclear command_line.wrefresh break [89, 121].include? c # Y, y end end |
#cd(dir, pushd: true) ⇒ Object
Change the current directory.
173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rfd.rb', line 173 def cd(dir, pushd: true) if dir.is_a?(Item) && dir.zip? cd_into_zip dir else target = dir if File.readable? target Dir.chdir target @dir_history << current_dir if current_dir && pushd @current_dir, @current_page, @current_row, @current_zip = target, 0, nil, nil main.activate_pane 0 end end end |
#cd_into_zip(zipfile) ⇒ Object
187 188 189 190 191 192 |
# File 'lib/rfd.rb', line 187 def cd_into_zip(zipfile) @current_zip = zipfile @dir_history << current_dir if current_dir @current_dir, @current_page, @current_row = zipfile.path, 0, nil main.activate_pane 0 end |
#chmod(mode = nil) ⇒ Object
Change the file permission of the selected files and directories.
Parameters
-
mode- Unix chmod string (e.g. +w, g-r, 755, 0644)
243 244 245 246 247 248 249 250 251 252 |
# File 'lib/rfd.rb', line 243 def chmod(mode = nil) return unless mode begin Integer mode mode = Integer mode.size == 3 ? "0#{mode}" : mode rescue ArgumentError end FileUtils.chmod mode, selected_items.map(&:path) ls end |
#chown(user_and_group) ⇒ Object
Change the file owner of the selected files and directories.
Parameters
-
user_and_group- user name and group name separated by : (e.g. alice, nobody:nobody, :admin)
258 259 260 261 262 263 |
# File 'lib/rfd.rb', line 258 def chown(user_and_group) return unless user_and_group user, group = user_and_group.split(':').map {|s| s == '' ? nil : s} FileUtils.chown user, group, selected_items.map(&:path) ls end |
#clipboard ⇒ Object
Copy selected files and directories’ path into clipboard on OSX.
488 489 490 |
# File 'lib/rfd.rb', line 488 def clipboard IO.popen('pbcopy', 'w') {|f| f << selected_items.map(&:path).join(' ')} if osx? end |
#cp(dest) ⇒ Object
Copy selected files and directories to the destination.
368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'lib/rfd.rb', line 368 def cp(dest) unless in_zip? src = (m = marked_items).any? ? m.map(&:path) : current_item.path FileUtils.cp_r src, (dest) else raise 'cping multiple items in .zip is not supported.' if selected_items.size > 1 Zip::File.open(current_zip.path) do |zip| entry = zip.find_entry(selected_items.first.name).dup entry.name, entry.name_length = dest, dest.size zip.instance_variable_get(:@entry_set) << entry end end ls end |
#current_item ⇒ Object
The file or directory on which the cursor is on.
129 130 131 |
# File 'lib/rfd.rb', line 129 def current_item items[current_row] end |
#delete ⇒ Object
Delete selected files and directories.
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
# File 'lib/rfd.rb', line 438 def delete unless in_zip? FileUtils.rm_rf selected_items.map(&:path) else Zip::File.open(current_zip.path) do |zip| zip.select {|e| selected_items.map(&:name).include? e.to_s}.each do |entry| if entry.name_is_directory? zip.dir.delete entry.to_s else zip.file.delete entry.to_s end end end end @current_row -= selected_items.count {|i| i.index <= current_row} ls end |
#draw_items ⇒ Object
Update the main window with the loaded files and directories. Also update the header.
312 313 314 315 |
# File 'lib/rfd.rb', line 312 def draw_items main.draw_items_to_each_pane (@displayed_items = items[current_page * max_items, max_items]) header_l.draw_path_and_page_number path: current_dir, current: current_page + 1, total: total_pages end |
#draw_marked_items ⇒ Object
Update the header information concerning currently marked files or directories.
589 590 591 592 |
# File 'lib/rfd.rb', line 589 def draw_marked_items items = marked_items header_r.draw_marked_items count: items.size, size: items.inject(0) {|sum, i| sum += i.size} end |
#draw_total_items ⇒ Object
Update the header information concerning total files and directories in the current directory.
595 596 597 |
# File 'lib/rfd.rb', line 595 def draw_total_items header_r.draw_total_items count: items.size, size: items.inject(0) {|sum, i| sum += i.size} end |
#edit ⇒ Object
Open current file or directory with the editor.
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
# File 'lib/rfd.rb', line 657 def edit execute_external_command do editor = ENV['EDITOR'] || 'vim' unless in_zip? system %Q[#{editor} "#{current_item.path}"] else begin tmpdir, tmpfile_name = nil Zip::File.open(current_zip.path) do |zip| tmpdir = Dir.mktmpdir FileUtils.mkdir_p File.join(tmpdir, File.dirname(current_item.name)) tmpfile_name = File.join(tmpdir, current_item.name) File.open(tmpfile_name, 'w') {|f| f.puts zip.file.read(current_item.name)} system %Q[#{editor} "#{tmpfile_name}"] zip.add(current_item.name, tmpfile_name) { true } end ls ensure FileUtils.remove_entry_secure tmpdir if tmpdir end end end end |
#fetch_items_from_filesystem_or_zip ⇒ Object
Fetch files from current directory or current .zip file.
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/rfd.rb', line 266 def fetch_items_from_filesystem_or_zip unless in_zip? @items = Dir.foreach(current_dir).map {|fn| stat = File.lstat File.join(current_dir, fn) Item.new dir: current_dir, name: fn, stat: stat, window_width: maxx }.to_a else @items = [Item.new(dir: current_dir, name: '.', stat: File.stat(current_dir), window_width: maxx), Item.new(dir: current_dir, name: '..', stat: File.stat(File.dirname(current_dir)), window_width: maxx)] zf = Zip::File.new current_dir zf.each {|entry| next if entry.name_is_directory? stat = zf.file.stat entry.name @items << Item.new(dir: current_dir, name: entry.name, stat: stat, window_width: maxx) } end end |
#find(str) ⇒ Object
Focus at the first file or directory of which name starts with the given String.
285 286 287 288 |
# File 'lib/rfd.rb', line 285 def find(str) index = items.index {|i| i.index > current_row && i.name.start_with?(str)} || items.index {|i| i.name.start_with? str} move_cursor index if index end |
#find_reverse(str) ⇒ Object
Focus at the last file or directory of which name starts with the given String.
291 292 293 294 |
# File 'lib/rfd.rb', line 291 def find_reverse(str) index = items.reverse.index {|i| i.index < current_row && i.name.start_with?(str)} || items.reverse.index {|i| i.name.start_with? str} move_cursor items.size - index - 1 if index end |
#first_page? ⇒ Boolean
Current page is the first page?
565 566 567 |
# File 'lib/rfd.rb', line 565 def first_page? current_page == 0 end |
#get_char ⇒ Object
Get a char as a String from user input.
605 606 607 608 |
# File 'lib/rfd.rb', line 605 def get_char c = Curses.getch c.chr if (0..255) === c end |
#grep(pattern = '.*') ⇒ Object
Search files and directories from the current directory, and update the screen.
-
pattern- Search pattern against file names in Ruby Regexp string.
Example
a : Search files that contains the letter “a” in their file name .*.pdf$ : Search PDF files
356 357 358 359 360 361 362 363 364 365 |
# File 'lib/rfd.rb', line 356 def grep(pattern = '.*') regexp = Regexp.new(pattern) fetch_items_from_filesystem_or_zip @items = items.shift(2) + items.select {|i| i.name =~ regexp} sort_items_according_to_current_direction switch_page 0 move_cursor 0 draw_total_items end |
#last_page? ⇒ Boolean
Do we have more pages?
570 571 572 |
# File 'lib/rfd.rb', line 570 def last_page? current_page == total_pages - 1 end |
#ls ⇒ Object
Fetch files from current directory. Then update each windows reflecting the newest information.
204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/rfd.rb', line 204 def ls fetch_items_from_filesystem_or_zip sort_items_according_to_current_direction @current_page ||= 0 draw_items move_cursor (current_row ? [current_row, items.size - 1].min : nil) draw_marked_items draw_total_items end |
#marked_items ⇒ Object
-
marked files and directories.
134 135 136 |
# File 'lib/rfd.rb', line 134 def marked_items items.select(&:marked?) end |
#max_items ⇒ Object
Number of files or directories that the current main window can show in a page.
307 308 309 |
# File 'lib/rfd.rb', line 307 def max_items main.max_items end |
#maxx ⇒ Object
Width of the currently active pane.
297 298 299 |
# File 'lib/rfd.rb', line 297 def maxx main.maxx end |
#maxy ⇒ Object
Height of the currently active pane.
302 303 304 |
# File 'lib/rfd.rb', line 302 def maxy main.maxy end |
#mkdir(dir) ⇒ Object
Create a new directory.
457 458 459 460 461 462 463 464 465 466 |
# File 'lib/rfd.rb', line 457 def mkdir(dir) unless in_zip? FileUtils.mkdir_p File.join(current_dir, dir) else Zip::File.open(current_zip.path) do |zip| zip.dir.mkdir dir end end ls end |
#move_cursor(row = nil) ⇒ Object
Move the cursor to specified row.
The main window and the headers will be updated reflecting the displayed files and directories. The row number can be out of range of the current page.
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/rfd.rb', line 149 def move_cursor(row = nil) if row page, item_index_in_page = row.divmod max_items if page != current_page switch_page page else if (prev_item = items[current_row]) main.draw_item prev_item end end main.activate_pane item_index_in_page / maxy @current_row = row else @current_row = 0 end item = items[current_row] main.draw_item item, current: true header_l.draw_current_file_info item header_l.wrefresh end |
#move_cursor_by_click(y: nil, x: nil) ⇒ Object
704 705 706 707 708 709 |
# File 'lib/rfd.rb', line 704 def move_cursor_by_click(y: nil, x: nil) if (idx = main.pane_index_at(y: y, x: x)) row = current_page * max_items + main.maxy * idx + y - main.begy move_cursor row if (row >= 0) && (row < items.size) end end |
#mv(dest) ⇒ Object
Move selected files and directories to the destination.
384 385 386 387 388 389 390 391 392 393 |
# File 'lib/rfd.rb', line 384 def mv(dest) unless in_zip? src = (m = marked_items).any? ? m.map(&:path) : current_item.path FileUtils.mv src, (dest) else raise 'mving multiple items in .zip is not supported.' if selected_items.size > 1 rename "#{selected_items.first.name}/#{dest}" end ls end |
#popd ⇒ Object
cd to the previous directory.
195 196 197 198 199 200 |
# File 'lib/rfd.rb', line 195 def popd if @dir_history.any? cd @dir_history.pop, pushd: false ls end end |
#process_command_line(preset_command: nil) ⇒ Object
Accept user input, and directly execute it as a Ruby method call to the controller.
Parameters
-
preset_command- A command that would be displayed at the command line before user input.
614 615 616 617 618 619 620 621 622 623 624 625 626 |
# File 'lib/rfd.rb', line 614 def process_command_line(preset_command: nil) prompt = preset_command ? ":#{preset_command} " : ':' command_line.set_prompt prompt cmd, *args = command_line.get_command(prompt: prompt).split(' ') if cmd && !cmd.empty? && respond_to?(cmd) self.public_send cmd, *args command_line.wclear command_line.wrefresh end rescue Interrupt command_line.wclear command_line.wrefresh end |
#process_shell_command ⇒ Object
Accept user input, and directly execute it in an external shell.
629 630 631 632 633 634 635 636 637 638 639 |
# File 'lib/rfd.rb', line 629 def process_shell_command command_line.set_prompt ':!' cmd = command_line.get_command(prompt: ':!')[1..-1] execute_external_command pause: true do system cmd end rescue Interrupt ensure command_line.wclear command_line.wrefresh end |
#rename(pattern) ⇒ Object
Rename selected files and directories.
Parameters
-
pattern- / separated Regexp like string
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/rfd.rb', line 399 def rename(pattern) from, to = pattern.split '/' from = Regexp.new from unless in_zip? selected_items.each do |item| name = item.name.gsub from, to FileUtils.mv item.path, File.join(current_dir, name) end else Zip::File.open(current_zip.path) do |zip| selected_items.each do |item| name = item.name.gsub from, to zip.rename item.name, name end end end ls end |
#run ⇒ Object
The main loop.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/rfd.rb', line 60 def run mouse_event = Curses::MEVENT.new loop do begin number_pressed = false case (c = Curses.getch) when Curses::KEY_RETURN enter when Curses::KEY_ESCAPE q when 32 # space space when 127 # DEL del when Curses::KEY_DOWN j when Curses::KEY_UP k when Curses::KEY_LEFT h when Curses::KEY_RIGHT l when Curses::KEY_CTRL_A..Curses::KEY_CTRL_Z chr = ((c - 1 + 65) ^ 0b0100000).chr public_send "ctrl_#{chr}" if respond_to?("ctrl_#{chr}") when 48..57 # ?0..?9 public_send c.chr number_pressed = true when 0..255 if respond_to? c.chr public_send c.chr else debug "key: #{c}" if ENV['DEBUG'] end when Curses::KEY_MOUSE if Curses.getmouse(mouse_event) == Curses::OK if Curses.BUTTON_CLICK(mouse_event[:bstate], 1) > 0 click y: mouse_event[:y], x: mouse_event[:x] elsif Curses.BUTTON_DOUBLE_CLICK(mouse_event[:bstate], 1) > 0 double_click y: mouse_event[:y], x: mouse_event[:x] end end else debug "key: #{c}" if ENV['DEBUG'] end @times = nil unless number_pressed rescue StopIteration raise rescue => e command_line.show_error e.to_s raise if ENV['DEBUG'] end end ensure Curses.endwin end |
#selected_items ⇒ Object
Marked files and directories or Array(the current file or directory).
. and .. will not be included.
141 142 143 |
# File 'lib/rfd.rb', line 141 def selected_items ((m = marked_items).any? ? m : Array(current_item)).reject {|i| %w(. ..).include? i.name} end |
#sort(direction = nil) ⇒ Object
Sort the whole files and directories in the current directory, then refresh the screen.
Parameters
-
direction- Sort order in a String.nil : order by name r : reverse order by name s, S : order by file size sr, Sr: reverse order by file size t : order by mtime tr : reverse order by mtime c : order by ctime cr : reverse order by ctime u : order by atime ur : reverse order by atime e : order by extname er : reverse order by extname
232 233 234 235 236 237 |
# File 'lib/rfd.rb', line 232 def sort(direction = nil) @direction, @current_page = direction, 0 sort_items_according_to_current_direction switch_page 0 move_cursor 0 end |
#sort_items_according_to_current_direction ⇒ Object
Sort the loaded files and directories in already given sort order.
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/rfd.rb', line 318 def sort_items_according_to_current_direction case @direction when nil @items = items.shift(2) + items.partition(&:directory?).flat_map(&:sort) when 'r' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort.reverse} when 'S', 's' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort_by {|i| -i.size}} when 'Sr', 'sr' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort_by(&:size)} when 't' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort {|x, y| y.mtime <=> x.mtime}} when 'tr' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort_by(&:mtime)} when 'c' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort {|x, y| y.ctime <=> x.ctime}} when 'cr' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort_by(&:ctime)} when 'u' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort {|x, y| y.atime <=> x.atime}} when 'ur' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort_by(&:atime)} when 'e' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort {|x, y| y.extname <=> x.extname}} when 'er' @items = items.shift(2) + items.partition(&:directory?).flat_map {|arr| arr.sort_by(&:extname)} end items.each.with_index {|item, index| item.index = index} end |
#spawn_panes(num) ⇒ Object
Change the number of columns in the main window.
118 119 120 121 |
# File 'lib/rfd.rb', line 118 def spawn_panes(num) main.spawn_panes num @current_row = @current_page = 0 end |
#switch_page(page) ⇒ Object
Move to the given page number.
Parameters
-
page- Target page number
583 584 585 586 |
# File 'lib/rfd.rb', line 583 def switch_page(page) @current_page = page draw_items end |
#symlink(name) ⇒ Object
Create a symlink to the current file or directory.
482 483 484 485 |
# File 'lib/rfd.rb', line 482 def symlink(name) FileUtils.ln_s current_item.path, name ls end |
#times ⇒ Object
Number of times to repeat the next command.
124 125 126 |
# File 'lib/rfd.rb', line 124 def times (@times || 1).to_i end |
#toggle_mark ⇒ Object
Swktch on / off marking on the current file or directory.
600 601 602 |
# File 'lib/rfd.rb', line 600 def toggle_mark main.toggle_mark current_item end |
#total_pages ⇒ Object
Number of pages in the current directory.
575 576 577 |
# File 'lib/rfd.rb', line 575 def total_pages items.size / max_items + 1 end |
#touch(filename) ⇒ Object
Create a new empty file.
469 470 471 472 473 474 475 476 477 478 479 |
# File 'lib/rfd.rb', line 469 def touch(filename) unless in_zip? FileUtils.touch File.join(current_dir, filename) else Zip::File.open(current_zip.path) do |zip| # zip.file.open(filename, 'w') {|_f| } #HAXX this code creates an unneeded temporary file zip.instance_variable_get(:@entry_set) << Zip::Entry.new(current_zip.path, filename) end end ls end |
#trash ⇒ Object
Soft delete selected files and directories.
If the OS is not OSX, performs the same as delete command.
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/rfd.rb', line 421 def trash unless in_zip? if osx? FileUtils.mv selected_items.map(&:path), File.('~/.Trash/') else #TODO support other OS FileUtils.rm_rf selected_items.map(&:path) end else return unless ask %Q[Trashing zip entries is not supported. Actually the files will be deleted. Are you sure want to proceed? (y/n)] delete end @current_row -= selected_items.count {|i| i.index <= current_row} ls end |
#unarchive ⇒ Object
Unarchive .zip and .tar.gz files within selected files and directories into current_directory.
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
# File 'lib/rfd.rb', line 513 def unarchive unless in_zip? zips, gzs = selected_items.partition(&:zip?).tap {|z, others| break [z, *others.partition(&:gz?)]} zips.each do |item| FileUtils.mkdir_p File.join(current_dir, item.basename) Zip::File.open(item.path) do |zip| zip.each do |entry| FileUtils.mkdir_p File.join(File.join(item.basename, File.dirname(entry.to_s))) zip.extract(entry, File.join(item.basename, entry.to_s)) { true } end end end gzs.each do |item| Zlib::GzipReader.open(item.path) do |gz| Gem::Package::TarReader.new(gz) do |tar| dest_dir = File.join current_dir, (gz.orig_name || item.basename).sub(/\.tar$/, '') tar.each do |entry| dest = nil if entry.full_name == '././@LongLink' dest = File.join dest_dir, entry.read.strip next end dest ||= File.join dest_dir, entry.full_name if entry.directory? FileUtils.mkdir_p dest, :mode => entry.header.mode elsif entry.file? FileUtils.mkdir_p dest_dir File.open(dest, 'wb') {|f| f.print entry.read} FileUtils.chmod entry.header.mode, dest elsif entry.header.typeflag == '2' # symlink File.symlink entry.header.linkname, dest end unless Dir.exist? dest_dir FileUtils.mkdir_p dest_dir File.open(File.join(dest_dir, gz.orig_name || item.basename), 'wb') {|f| f.print gz.read} end end end end end else Zip::File.open(current_zip.path) do |zip| zip.select {|e| selected_items.map(&:name).include? e.to_s}.each do |entry| FileUtils.mkdir_p File.join(current_zip.dir, current_zip.basename, File.dirname(entry.to_s)) zip.extract(entry, File.join(current_zip.dir, current_zip.basename, entry.to_s)) { true } end end end ls end |
#view ⇒ Object
Open current file or directory with the viewer.
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 |
# File 'lib/rfd.rb', line 682 def view pager = ENV['PAGER'] || 'less' execute_external_command do unless in_zip? system %Q[#{pager} "#{current_item.path}"] else begin tmpdir, tmpfile_name = nil Zip::File.open(current_zip.path) do |zip| tmpdir = Dir.mktmpdir FileUtils.mkdir_p File.join(tmpdir, File.dirname(current_item.name)) tmpfile_name = File.join(tmpdir, current_item.name) File.open(tmpfile_name, 'w') {|f| f.puts zip.file.read(current_item.name)} end system %Q[#{pager} "#{tmpfile_name}"] ensure FileUtils.remove_entry_secure tmpdir if tmpdir end end end end |
#zip(zipfile_name) ⇒ Object
Archive selected files and directories into a .zip file.
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
# File 'lib/rfd.rb', line 493 def zip(zipfile_name) return unless zipfile_name zipfile_name << '.zip' unless zipfile_name.end_with? '.zip' Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| selected_items.each do |item| next if item.symlink? if item.directory? Dir[File.join(item.path, '**/**')].each do |file| zipfile.add file.sub("#{current_dir}/", ''), file end else zipfile.add item.name, item.path end end end ls end |