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.
-
#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
637 638 639 640 641 642 643 644 645 646 |
# File 'lib/rfd.rb', line 637 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 |
# File 'lib/rfd.rb', line 173 def cd(dir, pushd: true) dir = load_item (dir) unless dir.is_a? Item unless dir.zip? Dir.chdir dir @current_zip = nil else @current_zip = dir end @dir_history << current_dir if current_dir && pushd @current_dir, @current_page, @current_row = dir, 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)
235 236 237 238 239 240 241 242 243 244 |
# File 'lib/rfd.rb', line 235 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)
250 251 252 253 254 255 |
# File 'lib/rfd.rb', line 250 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.
480 481 482 |
# File 'lib/rfd.rb', line 480 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.
360 361 362 363 364 365 366 367 368 369 370 371 372 373 |
# File 'lib/rfd.rb', line 360 def cp(dest) unless in_zip? src = (m = marked_items).any? ? m.map(&:path) : current_item 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) 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.
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/rfd.rb', line 430 def delete unless in_zip? FileUtils.rm_rf selected_items.map(&:path) else Zip::File.open(current_zip) 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.
304 305 306 307 |
# File 'lib/rfd.rb', line 304 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.path, current: current_page + 1, total: total_pages end |
#draw_marked_items ⇒ Object
Update the header information concerning currently marked files or directories.
581 582 583 584 |
# File 'lib/rfd.rb', line 581 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.
587 588 589 |
# File 'lib/rfd.rb', line 587 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.
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
# File 'lib/rfd.rb', line 649 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) 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.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/rfd.rb', line 258 def fetch_items_from_filesystem_or_zip unless in_zip? @items = Dir.foreach(current_dir).map {|fn| stat = File.lstat current_dir.join(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.
277 278 279 280 |
# File 'lib/rfd.rb', line 277 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.
283 284 285 286 |
# File 'lib/rfd.rb', line 283 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?
557 558 559 |
# File 'lib/rfd.rb', line 557 def first_page? current_page == 0 end |
#get_char ⇒ Object
Get a char as a String from user input.
597 598 599 600 |
# File 'lib/rfd.rb', line 597 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
348 349 350 351 352 353 354 355 356 357 |
# File 'lib/rfd.rb', line 348 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?
562 563 564 |
# File 'lib/rfd.rb', line 562 def last_page? current_page == total_pages - 1 end |
#ls ⇒ Object
Fetch files from current directory. Then update each windows reflecting the newest information.
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/rfd.rb', line 196 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.
299 300 301 |
# File 'lib/rfd.rb', line 299 def max_items main.max_items end |
#maxx ⇒ Object
Width of the currently active pane.
289 290 291 |
# File 'lib/rfd.rb', line 289 def maxx main.maxx end |
#maxy ⇒ Object
Height of the currently active pane.
294 295 296 |
# File 'lib/rfd.rb', line 294 def maxy main.maxy end |
#mkdir(dir) ⇒ Object
Create a new directory.
449 450 451 452 453 454 455 456 457 458 |
# File 'lib/rfd.rb', line 449 def mkdir(dir) unless in_zip? FileUtils.mkdir_p current_dir.join(dir) else Zip::File.open(current_zip) 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
696 697 698 699 700 701 |
# File 'lib/rfd.rb', line 696 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.
376 377 378 379 380 381 382 383 384 385 |
# File 'lib/rfd.rb', line 376 def mv(dest) unless in_zip? src = (m = marked_items).any? ? m.map(&:path) : current_item 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.
187 188 189 190 191 192 |
# File 'lib/rfd.rb', line 187 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.
606 607 608 609 610 611 612 613 614 615 616 617 618 |
# File 'lib/rfd.rb', line 606 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.
621 622 623 624 625 626 627 628 629 630 631 |
# File 'lib/rfd.rb', line 621 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
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 |
# File 'lib/rfd.rb', line 391 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, current_dir.join(name) if item.name != name end else Zip::File.open(current_zip) 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
224 225 226 227 228 229 |
# File 'lib/rfd.rb', line 224 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.
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
# File 'lib/rfd.rb', line 310 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
575 576 577 578 |
# File 'lib/rfd.rb', line 575 def switch_page(page) @current_page = page draw_items end |
#symlink(name) ⇒ Object
Create a symlink to the current file or directory.
474 475 476 477 |
# File 'lib/rfd.rb', line 474 def symlink(name) FileUtils.ln_s current_item, 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.
592 593 594 |
# File 'lib/rfd.rb', line 592 def toggle_mark main.toggle_mark current_item end |
#total_pages ⇒ Object
Number of pages in the current directory.
567 568 569 |
# File 'lib/rfd.rb', line 567 def total_pages items.size / max_items + 1 end |
#touch(filename) ⇒ Object
Create a new empty file.
461 462 463 464 465 466 467 468 469 470 471 |
# File 'lib/rfd.rb', line 461 def touch(filename) unless in_zip? FileUtils.touch current_dir.join(filename) else Zip::File.open(current_zip) 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, 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.
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
# File 'lib/rfd.rb', line 413 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.
505 506 507 508 509 510 511 512 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 |
# File 'lib/rfd.rb', line 505 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 current_dir.join(item.basename) Zip::File.open(item) do |zip| zip.each do |entry| FileUtils.mkdir_p 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) do |gz| Gem::Package::TarReader.new(gz) do |tar| dest_dir = current_dir.join (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) 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.
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 |
# File 'lib/rfd.rb', line 674 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) 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.
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
# File 'lib/rfd.rb', line 485 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[item.join('**/**')].each do |file| zipfile.add file.sub("#{current_dir}/", ''), file end else zipfile.add item.name, item end end end ls end |