module Cygnus
Constants
- CLEAR
- CONFIG_FILE
- CURMARK
- CURSOR_COLOR
REVERSE = “e[7m”
- GIGA_SIZE
code related to long listing of files
- GMARK
CONSTANTS
- KILO_SIZE
- MEGA_SIZE
- MSCROLL
- ON_BLUE
CLEAR
= “e[0m” BOLD = “e[1m” BOLD_OFF = “e[22m” RED = “e[31m” ON_RED = “e[41m” GREEN = “e[32m” YELLOW = “e[33m” BLUE = “e[1;34m”- SPACE
- VERSION
Public Instance Methods
TODO
# File lib/cygnus.rb, line 733 def TODOpost_cd $patt=nil $sta = $cursor = 0 $title = nil if $selected_files.size > 0 $selected_files = [] end $visual_block_start = nil $stact = 0 screen_settings # i think this will screw with the dir_pos since it is not filename based. enhance_file_list revert_dir_pos end
# File lib/cygnus.rb, line 1200 def ack pattern = get_line "Enter a pattern to search (ack): " return if pattern.nil? || pattern == "" $title = "Files found using 'ack' #{pattern}" #system("ack #{pattern}") #pause files = `ack -l #{pattern}`.split("\n") if files.size == 0 perror "No files found." else $files = files show_list end end
prompt user for file shortcut and return file or nil
# File lib/cygnus.rb, line 1007 def ask_hint text, deflt=nil f = nil #ch = get_char ch = get_single text if ch == "ENTER" return deflt end ix = get_index(ch, $viewport.size) f = $viewport[ix] if ix return f end
bind a key to an external command wich can be then be used for files
# File lib/cygnus.rb, line 1159 def bindkey_ext_command #print #pbold "Bind a capital letter to an external command" ch = get_single "Enter a capital letter to bind: " #ch = get_char return if ch == "Q" if ch =~ /^[A-Z]$/ print "Enter an external command to bind to #{ch}: " com = gets().chomp if com != "" print "Enter prompt for command (blank if same as command): " pro = gets().chomp pro = com if pro == "" end print "Pause after output [y/n]: " yn = get_char $bindings[ch] = "command_file #{pro} #{yn} #{com}" end end
refresh listing after some change like option change, or toggle
I think NCurses has a refresh which when called internally results in this chap getting called since both are included. or maybe App or somehting has a refresh
# File lib/cygnus.rb, line 358 def c_refresh $filterstr ||= "M" #$files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}#{$filterstr})'`.split("\n") $patt=nil $title = nil display_dir end
# File lib/cygnus.rb, line 333 def c_system command w = @window || @form.window w.hide Ncurses.endwin ret = system command Ncurses.refresh w.show return ret end
# File lib/cygnus.rb, line 878 def child_dirs $title = "Child directories" $files = `zsh -c 'print -rl -- *(/#{$sorto}#{$hidden}M)'`.split("\n") end
moves column offset so we can reach unindexed columns or entries
0 forward and any other back/prev
# File lib/cygnus.rb, line 1034 def column_next dir=0 if dir == 0 $stact += $grows $stact = 0 if $stact >= $viewport.size else $stact -= $grows $stact = 0 if $stact < 0 end end
print in columns ary - array of data sz - lines in one column This is the original which did not format or color, but since we cannot truncate unless we have unformatted data i need to mix the functionality into columnate_with_indexing
# File lib/cygnus.rb, line 194 def columnate ary, sz buff=Array.new return buff if ary.nil? || ary.size == 0 # ix refers to the index in the complete file list, wherease we only show 60 at a time ix=0 while true ## ctr refers to the index in the column ctr=0 while ctr < sz f = ary[ix] # deleted truncate and pad part since we expect cols to be sized same if buff[ctr] buff[ctr] += f else buff[ctr] = f end ctr+=1 ix+=1 break if ix >= ary.size end break if ix >= ary.size end return buff end
print in columns ary - array of data sz - lines in one column
# File lib/cygnus.rb, line 95 def columnate_with_indexing ary, sz buff=Array.new $log.warn "columnate_with_indexing got nil list " unless ary return buff if ary.nil? || ary.size == 0 # determine width based on number of files to show # if less than sz then 1 col and full width # wid = 30 ars = ary.size ars = [$pagesize, ary.size].min # 2 maybe for borders also d = 0 if ars <= sz wid = $gcols - d else tmp = (ars * 1.000/ sz).ceil wid = $gcols / tmp - d end # ix refers to the index in the complete file list, wherease we only show 60 at a time ix=0 while true ## ctr refers to the index in the column ctr=0 while ctr < sz cur=SPACE cur = CURMARK if ix + $sta == $cursor f = ary[ix] if $long_listing begin # one of zsh's flags adds not just / but @ * and a space, so the a FNF error comes unless File.exist? f last = f[-1] if last == " " || last == "@" || last == '*' stat = File.stat(f.chop) end else stat = File.stat(f) end f = "%10s %s %s" % [readable_file_size(stat.size,1), date_format(stat.mtime), f] rescue Exception => e f = "%10s %s %s" % ["?", "??????????", f] end end # be careful of modifying f or original array gets modified XXX k = get_shortcut ix isdir = f[-1] == "/" fsz = f.size + k.to_s.size + 0 fsz = f.size + 1 if fsz > wid # truncated since longer f = f[0, wid-2]+"$ " ## we do the coloring after trunc so ANSI escpe seq does not get get #if ix + $sta == $cursor #f = "#{CURSOR_COLOR}#{f}#{CLEAR}" #end else ## we do the coloring before padding so the entire line does not get padded, only file name #if ix + $sta == $cursor #f = "#{CURSOR_COLOR}#{f}#{CLEAR}" #end f = f.ljust(wid) # pad with spaces #f << " " * (wid-fsz) #f = f + " " * (wid-fsz) end # now we add the shortcut with the coloring (we need to adjust the space of the shortcut) # colr = "white" colr = "blue, bold" if isdir # this directly modified the damned index resulting in searches failing #k << " " if k.length == 1 k = k + " " if k.length == 1 f = "#{cur}#[fg=yellow, bold]#{k}#[end] #[fg=#{colr}]#{f}#[end]" if buff[ctr] buff[ctr] += f else buff[ctr] = f end ctr+=1 ix+=1 break if ix >= ary.size end break if ix >= ary.size end return buff end
# File lib/cygnus.rb, line 1151 def columns_incdec howmany $gviscols += howmany.to_i $gviscols = 1 if $gviscols < 1 $gviscols = 6 if $gviscols > 6 $pagesize = $grows * $gviscols end
generic external command program prompt is the user friendly text of command such as list for ls, or extract for dtrx, page for less pauseyn is whether to pause after command as in file or ls
# File lib/cygnus.rb, line 983 def command_file prompt, *command pauseyn = command.shift command = command.join " " #print "[#{prompt}] Choose a file [#{$view[$cursor]}]: " t = "[#{prompt}] Choose a file [#{$view[$cursor]}]: " file = ask_hint t, $view[$cursor] #print "#{prompt} :: Enter file shortcut: " #file = ask_hint perror "Command Cancelled" unless file return unless file file = File.expand_path(file) if File.exists? file file = Shellwords.escape(file) pbold "#{command} #{file} (press a key)" c_system "#{command} #{file}" pause if pauseyn == "y" c_refresh else perror "File #{file} not found" end end
toggle command mode
# File lib/cygnus.rb, line 421 def command_mode if $mode == 'COM' $mode = nil return end $mode = 'COM' end
read dirs and files and bookmarks from file
# File lib/cygnus.rb, line 749 def config_read #f = File.expand_path("~/.zfminfo") f = File.expand_path(CONFIG_FILE) if File.readable? f load f # maybe we should check for these existing else crash will happen. $used_dirs.push(*(DIRS.split ":")) $used_dirs.concat get_env_paths $visited_files.push(*(FILES.split ":")) #$bookmarks.push(*bookmarks) if bookmarks chars = ('A'..'Z').to_a chars.concat( ('0'..'9').to_a ) chars.each do |ch| if Kernel.const_defined? "BM_#{ch}" $bookmarks[ch] = Kernel.const_get "BM_#{ch}" end end end end
save dirs and files and bookmarks to a file
# File lib/cygnus.rb, line 782 def config_write # Putting it in a format that zfm can also read and write f1 = File.expand_path("~/.cygnusinfo") #f1 = File.expand_path(CONFIG_FILE) d = $used_dirs.join ":" f = $visited_files.join ":" File.open(f1, 'w+') do |f2| # use "\n" for two lines of text f2.puts "DIRS=\"#{d}\"" f2.puts "FILES=\"#{f}\"" $bookmarks.each_pair { |k, val| f2.puts "BM_#{k}=\"#{val}\"" #f2.puts "BOOKMARKS[\"#{k}\"]=\"#{val}\"" } end $writing = $modified = false end
accept a character to save this dir as a bookmark
# File lib/cygnus.rb, line 801 def create_bookmark ch = get_single "Enter A to Z or 0-9 for bookmark: " #ch = get_char if ch =~ /^[0-9A-Z]$/ #$bookmarks[ch] = "#{Dir.pwd}:#{$cursor}" # # The significance of putting a : and not a / is that with a # : the dir will be opened with cursor on same object it was on, and not # go into the dir. e.g, If bookmark is created with cursor on a dir, we don't want # it to go into the dir. $bookmarks[ch] = "#{Dir.pwd}:#{$view[$cursor]}" $modified = true else perror "Bookmark must be upper-case character or number." end end
# File lib/cygnus.rb, line 1257 def cursor_dn moveto(pos() + 1) end
some cursor movement functions
# File lib/cygnus.rb, line 1251 def cursor_scroll_dn moveto(pos() + MSCROLL) end
# File lib/cygnus.rb, line 1254 def cursor_scroll_up moveto(pos() - MSCROLL) end
# File lib/cygnus.rb, line 1260 def cursor_up moveto(pos() - 1) end
format date for file given stat
# File lib/cygnus.rb, line 86 def date_format t t.strftime "%Y/%m/%d" end
# File lib/cygnus.rb, line 975 def delete_file file_actions :delete end
# File lib/cygnus.rb, line 882 def dirtree $title = "Child directories" $files = `zsh -c 'print -rl -- **/*(/#{$sorto}#{$hidden}M)'`.split("\n") end
If there’s a short file list, take recently mod and accessed folders and put latest files from there and insert it here. I take both since recent mod can be binaries / object files and gems created by a process, and not actually edited files. Recent accessed gives latest source, but in some cases even this can be misleading since running a program accesses include files.
# File lib/cygnus.rb, line 1433 def enhance_file_list return unless $enhanced_mode # if only one entry and its a dir # get its children and maybe the recent mod files a few # zsh gives errors which stick on stdscr and don't get off! # Rather than using N I'll try to convert to ruby, but then we lose # similarity to cetus and its tough to redo all the sorting stuff. if $files.size == 1 # its a dir, let give the next level at least if $files.first[-1] == "/" d = $files.first #f = `zsh -c 'print -rl -- #{d}*(omM)'`.split("\n") f = get_file_list d if f && f.size > 0 $files.concat f $files.concat get_important_files(d) return end else # just a file, not dirs here return end end # # check if a ruby project dir, although it could be a backup file too, # if so , expand lib and maby bin, put a couple recent files # if $files.index("Gemfile") || $files.grep(/\.gemspec/).size > 0 # usually the lib dir has only one file and one dir flg = false $files.concat get_important_files(Dir.pwd) if $files.index("lib/") f = `zsh -c 'print -rl -- lib/*(om[1,5]MN)'`.split("\n") if f && f.size() > 0 insert_into_list("lib/", f) flg = true end dd = File.basename(Dir.pwd) if f.index("lib/#{dd}/") f = `zsh -c 'print -rl -- lib/#{dd}/*(om[1,5]MN)'`.split("\n") if f && f.size() > 0 insert_into_list("lib/#{dd}/", f) flg = true end end end if $files.index("bin/") f = `zsh -c 'print -rl -- bin/*(om[1,5]MN)'`.split("\n") insert_into_list("bin/", f) if f && f.size() > 0 flg = true end return if flg # lib has a dir in it with the gem name end return if $files.size > 15 ## first check accessed else modified will change accessed moda = `zsh -c 'print -rn -- *(/oa[1]MN)'` if moda && moda != "" modf = `zsh -c 'print -rn -- #{moda}*(oa[1]MN)'` if modf && modf != "" insert_into_list moda, modf end modm = `zsh -c 'print -rn -- #{moda}*(om[1]MN)'` if modm && modm != "" && modm != modf insert_into_list moda, modm end end ## get last modified dir modm = `zsh -c 'print -rn -- *(/om[1]MN)'` if modm != moda modmf = `zsh -c 'print -rn -- #{modm}*(oa[1]MN)'` insert_into_list modm, modmf modmf1 = `zsh -c 'print -rn -- #{modm}*(om[1]MN)'` insert_into_list(modm, modmf1) if modmf1 != modmf else # if both are same then our options get reduced so we need to get something more # If you access the latest mod dir, then come back you get only one, since mod and accessed # are the same dir, so we need to find the second modified dir end end
take regex from user, to run on files on screen, user can filter file names
# File lib/cygnus.rb, line 446 def enter_regex patt = get_line "Enter (regex) pattern: " #$patt = gets().chomp #$patt = Readline::readline('>', true) $patt = patt return patt end
clear sort order and refresh listing, used typically if you are in some view such as visited dirs or files
# File lib/cygnus.rb, line 345 def escape $sorto = nil $sorto = $default_sort_order $viewctr = 0 $title = nil $filterstr = "M" visual_block_clear c_refresh end
# File lib/cygnus.rb, line 640 def extras h = { "1" => :one_column, "2" => :multi_column, :c => :columns, :r => :config_read , :w => :config_write} ch, menu_text = menu "Extras Menu", h case menu_text when :one_column $pagesize = $grows when :multi_column #$pagesize = 60 $pagesize = $grows * $gviscols when :columns ch = get_single "How many columns to show: 1-6 [current #{$gviscols}]? " #ch = get_char ch = ch.to_i if ch > 0 && ch < 7 $gviscols = ch.to_i $pagesize = $grows * $gviscols end end end
# File lib/cygnus.rb, line 1214 def ffind pattern = get_line "Enter a file name pattern to find: " return if pattern.nil? || pattern == "" $title = "Files found using 'find' #{pattern}" files = `find . -name '#{pattern}'`.split("\n") if files.size == 0 perror "No files found." else $files = files show_list end end
currently i am only passing the action in from the list there as a key I should be able to pass in new actions that are external commands
# File lib/cygnus.rb, line 1045 def file_actions action=nil h = { :d => :delete, :m => :move, :r => :rename, :v => ENV["EDITOR"] || :vim, :c => :copy, :C => :chdir, :l => :less, :s => :most , :f => :file , :o => :open, :x => :dtrx, :z => :zip } #acttext = h[action.to_sym] || action acttext = action || "" file = nil sct = $selected_files.size if sct > 0 text = "#{sct} files" file = $selected_files else #print "[#{acttext}] Choose a file [#{$view[$cursor]}]: " t = "[#{acttext}] Choose a file [#{$view[$cursor]}]: " file = ask_hint t, $view[$cursor] return unless file text = file end case file when Array # escape the contents and create a string files = Shellwords.join(file) when String files = Shellwords.escape(file) end ch = nil if action menu_text = action else ch, menu_text = menu "File Menu for #{text}", h menu_text = :quit if ch == "q" end return unless menu_text case menu_text.to_sym when :quit when :delete ch = get_single "rmtrash #{files} ?[yn]: " #print "rmtrash #{files} ?[yn]: " #ch = get_char return if ch != "y" c_system "rmtrash #{files}" c_refresh when :move #print "move #{text} to : " #target = gets().chomp #target = Readline::readline('>', true) target = get_line "move #{text} to : " text=File.expand_path(text) return if target.nil? || target == "" if File.directory? target FileUtils.mv text, target c_refresh else perror "Target not a dir" end when :copy target = get_line "copy #{text} to : " #target = Readline::readline('>', true) return if target.nil? || target == "" text=File.expand_path(text) target = File.basename(text) if target == "." if File.exists? target perror "Target (#{target}) exists" else FileUtils.cp text, target c_refresh end when :chdir change_dir File.dirname(text) when :zip target = get_line "Archive name: " #target = gets().chomp #target = Readline::readline('>', true) return if target.nil? || target == "" # don't want a blank space or something screwing up if target && target.size > 3 if File.exists? target perror "Target (#{target}) exists" else c_system "tar zcvf #{target} #{files}" c_refresh end end when :rename when :most, :less, :vim, ENV['EDITOR'] c_system "#{menu_text} #{files}" else return unless menu_text $log.debug "XXX: menu_text #{menu_text.to_sym}" get_single "#{menu_text} #{files}" #pause #print c_system "#{menu_text} #{files}" pause c_refresh end # remove non-existent files from select list due to move or delete or rename or whatever if sct > 0 $selected_files.reject! {|x| x = File.expand_path(x); !File.exists?(x) } end end
# File lib/cygnus.rb, line 1302 def file_matching? file, patt file =~ /#{patt}/ end
# File lib/cygnus.rb, line 1333 def filetype f return nil unless f f = Shellwords.escape(f) s = `file #{f}` if s.index "text" return :text elsif s.index(/[Zz]ip/) return :zip elsif s.index("archive") return :zip elsif s.index "image" return :image elsif s.index "data" return :text else return :directory if File.directory? f end return :unknown end
formats the data with number, mark and details
# File lib/cygnus.rb, line 223 def format ary alert "deprecated, can be removed if not called" #buff = Array.new buff = Array.new(ary.size) return buff if ary.nil? || ary.size == 0 # determine width based on number of files to show # if less than sz then 1 col and full width # # ix refers to the index in the complete file list, wherease we only show 60 at a time ix=0 ctr=0 ary.each do |f| ## ctr refers to the index in the column ind = get_shortcut(ix) mark=SPACE cur=SPACE cur = CURMARK if ix + $sta == $cursor mark=GMARK if $selected_files.index(ary[ix]) if $long_listing begin unless File.exist? f last = f[-1] if last == " " || last == "@" || last == '*' stat = File.stat(f.chop) end else stat = File.stat(f) end f = "%10s %s %s" % [readable_file_size(stat.size,1), date_format(stat.mtime), f] rescue Exception => e f = "%10s %s %s" % ["?", "??????????", f] end end s = "#{ind}#{mark}#{cur}#{f}" # I cannot color the current line since format does the chopping # so not only does the next lines alignment get skeweed, but also if the line is truncated # then the color overflows. #if ix + $sta == $cursor #s = "#{RED}#{s}#{CLEAR}" #end buff[ctr] = s ctr+=1 ix+=1 end return buff end
I thin we need to make this like the command line one TODO
# File lib/cygnus.rb, line 910 def get_char c = @window.getchar case c when 13,10 return "ENTER" when 32 return "SPACE" when 127 return "BACKSPACE" when 27 return "ESCAPE" end keycode_tos c # if c > 32 && c < 127 #return c.chr #end ## use keycode_tos from Utils. end
# File lib/cygnus.rb, line 768 def get_env_paths files = [] %w{ GEM_HOME PYTHONHOME}.each do |p| d = ENV[p] files.push d if d end %w{ RUBYLIB RUBYPATH GEM_PATH PYTHONPATH }.each do |p| d = ENV[p] files.concat d.split(":") if d end return files end
checks various lists like visited_files and bookmarks to see if files from this dir or below are in it. More to be used in a dir with few files.
# File lib/cygnus.rb, line 1529 def get_important_files dir list = [] l = dir.size + 1 s = nil ($visited_files + $bookmarks.values).each do |e| if e.index(dir) == 0 #list << e[l..-1] s = e[l..-1] next unless s if s.index ":" s = s[0, s.index(":")] + "/" end # only insert if the file is in a deeper dir, otherwise we'll be duplicating files from this folder list << s if s.index "/" end end # bookmarks have : which needs to be removed #list1 = $bookmarks.values.select do |e| #e.index(dir) == 0 #end #list.concat list1 return list end
returns the integer offset in view (file array based on a-y za-zz and Za - Zz
Called when user types a key
should we even ask for a second key if there are not enough rows What if we want to also trap z with numbers for other purposes
# File lib/cygnus.rb, line 958 def get_index key, vsz=999 i = $IDX.index(key) return i+$stact if i #sz = $IDX.size zch = nil if vsz > 25 if key == "z" || key == "Z" #print key zch = get_char #print zch i = $IDX.index("#{key}#{zch}") return i+$stact if i end end return nil end
identical to get_string but does not show as a popup with buttons, just ENTER This is required if there are multiple inputs required and having several get_strings one after the other seems really odd due to multiple popups Unlike, get_string this does not return a nil if C-c pressed. Either returns a string if ENTER pressed or a blank if C-c or Double Escape. So only blank to be checked
# File lib/cygnus.rb, line 1578 def get_line text, config={} begin w = one_line_window form = RubyCurses::Form.new w f = Field.new form, :label => text, :row => 0, :col => 1 form.repaint w.wrefresh while((ch = w.getchar()) != FFI::NCurses::KEY_F10 ) break if ch == 13 if ch == 3 || ch == 27 || ch == 2727 return "" end begin form.handle_key(ch) w.wrefresh rescue => err $log.debug( err) if err $log.debug(err.backtrace.join("\n")) if err textdialog ["Error in Messagebox: #{err} ", *err.backtrace], :title => "Exception" w.refresh # otherwise the window keeps showing (new FFI-ncurses issue) $error_message.value = "" ensure end end # while loop ensure w.destroy w = nil end return f.text end
return shortcut for an index (offset in file array)
use 2 more arrays to make this faster
if z or Z take another key if there are those many in view Also, display ROWS * COLS so now we are not limited to 60.
# File lib/cygnus.rb, line 947 def get_shortcut ix return "<" if ix < $stact ix -= $stact i = $IDX[ix] return i if i return "->" end
prints a prompt at bottom of screen, takes a character and returns textual representation of character (as per get_char
) and not the int that window.getchar returns. It uses a window, so underlying text is not touched.
# File lib/cygnus.rb, line 1557 def get_single text, config={} w = one_line_window x = y = 0 color = config[:color_pair] || $datacolor color=Ncurses.COLOR_PAIR(color); w.attron(color); w.mvprintw(x, y, "%s" % text); w.attroff(color); w.wrefresh Ncurses::Panel.update_panels chr = get_char w.destroy w = nil return chr end
accept dir to goto and change to that ( can be a file too)
# File lib/cygnus.rb, line 378 def goto_dir begin path = get_line "Enter path: " return if path.nil? || path == "" rescue Exception => ex perror "Cancelled cd, press a key" return end f = File.expand_path(path) unless File.directory? f ## check for env variable tmp = ENV[path] if tmp.nil? || !File.directory?( tmp ) ## check for dir in home tmp = File.expand_path("~/#{path}") if File.directory? tmp f = tmp end else f = tmp end end open_file f end
This actually filters, in zfm it goes to that entry since we have a cursor there
# File lib/cygnus.rb, line 433 def goto_entry_starting_with fc=nil unless fc fc = get_single "Entries starting with: " #fc = get_char end return if fc.size != 1 ## this is wrong and duplicates the functionality of / # It shoud go to cursor of item starting with fc $patt = "^#{fc}" end
position cursor on a specific line which could be on a nother page therefore calculate the correct start offset of the display also.
# File lib/cygnus.rb, line 1325 def goto_line pos pages = ((pos * 1.00)/$pagesize).ceil pages -= 1 #$sta = pages * $pagesize + 1 $sta = pages * $pagesize + 0 $cursor = pos #$log.debug "XXX: GOTO_LINE #{$sta} :: #{$cursor}" end
# File lib/cygnus.rb, line 428 def goto_parent_dir change_dir ".." end
# File lib/cygnus.rb, line 1517 def insert_into_list dir, file ## earlier we were inserting these files at helpful points (before the dirs), but they are touch to find. # I think it;s better to put at end #ix = $files.index(dir) #raise "something wrong can find #{dir}." unless ix #$files.insert ix, *file $files.push *file end
# File lib/cygnus.rb, line 1226 def locate pattern = get_line "Enter a file name pattern to locate: " return if pattern.nil? || pattern == "" $title = "Files found using 'locate' #{pattern}" files = `locate #{pattern}`.split("\n") files.reject! {|x| x = File.expand_path(x); !File.exists?(x) } if files.size == 0 perror "No files found." else $files = files show_list end end
# File lib/cygnus.rb, line 1267 def moveto pos orig = $cursor $cursor = pos $cursor = [$cursor, $view.size - 1].min $cursor = [$cursor, 0].max star = [orig, $cursor].min fin = [orig, $cursor].max if $visual_mode # PWD has to be there in selction if $selected_files.index $view[$cursor] # this depends on the direction $selected_files = $selected_files - $view[star..fin] ## current row remains in selection always. $selected_files.push $view[$cursor] else $selected_files.concat $view[star..fin] end end end
# File lib/cygnus.rb, line 1368 def newdir #print #print "Enter directory name: " #str = Readline::readline('>', true) str = get_line "Enter directory name: " return if str.nil? || str == "" if File.exists? str perror "#{str} exists." return end begin FileUtils.mkdir str $used_dirs.insert(0, str) if File.exists?(str) c_refresh rescue Exception => ex perror "Error in newdir: #{ex}" end end
# File lib/cygnus.rb, line 1386 def newfile #print str = get_line "Enter file name: " #str = Readline::readline('>', true) return if str.nil? || str == "" c_system "$EDITOR #{str}" $visited_files.insert(0, str) if File.exists?(str) c_refresh end
# File lib/cygnus.rb, line 453 def next_page # FIXME cursor position, take logic from zfm page calc $sta += $pagesize $cursor = $sta if $cursor < $sta end
# File lib/cygnus.rb, line 939 def pause text=" Press a key ..." get_single text #get_char end
# File lib/cygnus.rb, line 929 def pbold text #puts "#{BOLD}#{text}#{BOLD_OFF}" get_single text, :color_pair => $reversecolor end
# File lib/cygnus.rb, line 933 def perror text ##puts "#{RED}#{text}#{CLEAR}" #get_char #alert text get_single text + " Press a key...", :color_pair => $errorcolor end
part copied and changed from change_dir since we don’t dir going back on top or we’ll be stuck in a cycle
# File lib/cygnus.rb, line 714 def pop_dir # the first time we pop, we need to put the current on stack if !$visited_dirs.index(Dir.pwd) $visited_dirs.push Dir.pwd end ## XXX make sure thre is something to pop d = $visited_dirs.delete_at 0 ## XXX make sure the dir exists, cuold have been deleted. can be an error or crash otherwise $visited_dirs.push d Dir.chdir d display_dir return # old stuff with zsh $filterstr ||= "M" $files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}#{$filterstr})'`.split("\n") post_cd end
# File lib/cygnus.rb, line 1263 def pos $cursor end
# File lib/cygnus.rb, line 458 def prev_page # FIXME cursor position, take logic from zfm page calc $sta -= $pagesize $cursor = $sta end
# File lib/cygnus.rb, line 480 def print_help h = @bindings row = 1 list = [] longestval = h.values.max_by(&:length) llen = longestval.length # they must all be of same size so i can easily columnate h.each_pair { |k, v| list << " #[fg=yellow, bold]#{k.ljust(6)}#[/end] #[fg=green]#{v.ljust(llen)}#[/end]" } lines = FFI::NCurses.LINES - row list = columnate list, lines - 2 config = {} config[:row] = row config[:col] = 1 config[:title] = "Key Bindings" #config[:width] = [longestval.length + 5, FFI::NCurses.COLS - 5].min config[:width] = FFI::NCurses.COLS - config[:col] config[:height] = lines ch = padpopup list, config return unless ch end
create a list of dirs in which some action has happened, for saving
# File lib/cygnus.rb, line 906 def push_used_dirs d=Dir.pwd $used_dirs.index(d) || $used_dirs.push(d) end
# File lib/cygnus.rb, line 853 def quit_command if $modified s = "" s << "Press w to save bookmarks before quitting. " if $modified s << "Press another q to quit " ch = get_single s #ch = get_char else $quitting = true end $quitting = true if ch == "q" $quitting = $writing = true if ch == "w" end
Return the file size with a readable style.
# File lib/cygnus.rb, line 76 def readable_file_size(size, precision) case #when size == 1 : "1 B" when size < KILO_SIZE then "%d B" % size when size < MEGA_SIZE then "%.#{precision}f K" % (size / KILO_SIZE) when size < GIGA_SIZE then "%.#{precision}f M" % (size / MEGA_SIZE) else "%.#{precision}f G" % (size / GIGA_SIZE) end end
# File lib/cygnus.rb, line 894 def recent_files # print -rl -- **/*(Dom[1,10]) $title = "Recent files" $files = `zsh -c 'print -rl -- **/*(Dom[1,15])'`.split("\n") end
Editing of the User Dir List. remove current entry from used dirs list, since we may not want some entries being there
# File lib/cygnus.rb, line 1400 def remove_from_list if $selected_files.size > 0 sz = $selected_files.size ch = get_single "Remove #{sz} files from used list (y)?: " #ch = get_char return if ch != "y" $used_dirs = $used_dirs - $selected_files $visited_files = $visited_files - $selected_files unselect_all $modified = true return end #print ## what if selected some rows file = $view[$cursor] ch = get_single "Remove #{file} from used list (y)?: " #ch = get_char return if ch != "y" file = File.expand_path(file) if File.directory? file $used_dirs.delete(file) else $visited_files.delete(file) end c_refresh $modified = true end
generic method to take cursor to next position for a given condition
# File lib/cygnus.rb, line 1307 def return_next_match binding, *args first = nil ix = 0 $view.each_with_index do |elem,ii| if binding.call(elem, *args) first ||= ii if ii > $cursor ix = ii break end end end return first if ix == 0 return ix end
# File lib/cygnus.rb, line 1357 def revert_dir_pos $sta = 0 $cursor = 0 a = $dir_position[Dir.pwd] if a $sta = a.first $cursor = a[1] raise "sta is nil for #{Dir.pwd} : #{$dir_position[Dir.pwd]}" unless $sta raise "cursor is nil" unless $cursor end end
run command on given file/s
Accepts command from user After putting readline in place of gets, pressing a C-c has a delayed effect. It goes intot exception bloack after executing other commands and still does not do the return !
# File lib/cygnus.rb, line 308 def run_command f files=nil case f when Array # escape the contents and create a string files = Shellwords.join(f) when String files = Shellwords.escape(f) end begin # TODO put all this get_line stuff into field history command = get_line "Run a command on #{files}: " return if command.size == 0 command2 = get_line "Second part of command: " # FIXME we may need to go into cooked mode and all that for this # cat and most mess with the output using system c_system "#{command} #{files} #{command2}" rescue Exception => ex perror "Canceled command, (#{ex}) press a key" return end c_refresh push_used_dirs Dir.pwd end
# File lib/cygnus.rb, line 1353 def save_dir_pos return if $sta == 0 && $cursor == 0 $dir_position[Dir.pwd] = [$sta, $cursor] end
check screen size and accordingly adjust some variables
# File lib/cygnus.rb, line 1022 def screen_settings # TODO these need to become part of our new full_indexer class, not hang about separately. $glines=%x(tput lines).to_i $gcols=%x(tput cols).to_i # this depends now on textpad size not screen size TODO FIXME $grows = $glines - 1 $pagesize = 60 #$gviscols = 3 $pagesize = $grows * $gviscols end
select all files
# File lib/cygnus.rb, line 373 def select_all $selected_files = $view.dup end
# File lib/cygnus.rb, line 699 def select_bookmarks $title = "Bookmarks" $files = $bookmarks.values.collect do |x| if x.include? ":" ix = x.index ":" x[0,ix] else x end end #show_list files end
# File lib/cygnus.rb, line 899 def select_current ## vp is local there, so i can do $vp[0] #open_file $view[$sta] if $view[$sta] open_file $view[$cursor] if $view[$cursor] end
select file based on key pressed
# File lib/cygnus.rb, line 275 def select_hint view, ch # a to y is direct # if z or Z take a key IF there are those many # ix = get_index(ch, view.size) if ix f = view[ix] return unless f $cursor = $sta + ix if $mode == 'SEL' toggle_select f elsif $mode == 'COM' run_command f else open_file f end #selectedix=ix end end
# File lib/cygnus.rb, line 687 def select_used_dirs $title = "Used Directories" $files = $used_dirs.uniq #show_list end
# File lib/cygnus.rb, line 692 def select_visited_files # not yet a unique list, needs to be unique and have latest pushed to top $title = "Visited Files" files = $visited_files.uniq show_list files $title = nil end
toggle mode to selection or not In selection, pressed hotkey selects a file without opening, one can keep selecting (or deselecting).
# File lib/cygnus.rb, line 408 def selection_mode_toggle if $mode == 'SEL' # we seem to be coming out of select mode with some files if $selected_files.size > 0 run_command $selected_files end $mode = nil else #$selection_mode = !$selection_mode $mode = 'SEL' end end
# File lib/cygnus.rb, line 463 def show_marks list = [] $bookmarks.each_pair { |k, v| list << " #[fg=yellow, bold]#{k}#[/end] #[fg=green]#{v}#[/end]" } # s="#[fg=green]hello there#[fg=yellow, bg=black, dim]" config = {} longestval = $bookmarks.values.max_by(&:length) config[:title] = "Bookmarks" config[:width] = [longestval.length + 5, FFI::NCurses.COLS - 5].min $log.debug "XXX: LONGEST #{longestval}, #{longestval.length}" ch = padpopup list, config return unless ch #$bookmarks.each_pair { |k, v| puts "#{k.ljust(7)} => #{v}" } #puts #print "Enter bookmark to goto: " #ch = get_char goto_bookmark(ch) if ch =~ /^[0-9A-Z]$/ end
# File lib/cygnus.rb, line 817 def subcommand begin command = get_line "Enter command: " #command = gets().chomp #command = Readline::readline('>', true) return if command == "" rescue Exception => ex return end if command == "q" if $modified ch = get_single "Do you want to save bookmarks? (y/n): " #ch = get_char if ch == "y" $writing = true $quitting = true elsif ch == "n" $quitting = true print "Quitting without saving bookmarks" else perror "No action taken." end else $quitting = true end elsif command == "wq" $quitting = true $writing = true elsif command == "x" $quitting = true $writing = true if $modified elsif command == "p" c_system "echo $PWD | pbcopy" get_single "Stored PWD in clipboard (using pbcopy)" end end
toggle selection state of file
# File lib/cygnus.rb, line 296 def toggle_select f if $selected_files.index f $selected_files.delete f else $selected_files.push f end end
Get a full recursive listing of what’s in this dir - useful for small projects with more structure than files.
# File lib/cygnus.rb, line 889 def tree # Caution: use only for small projects, don't use in root. $title = "Full Tree" $files = `zsh -c 'print -rl -- **/*(#{$sorto}#{$hidden}M)'`.split("\n") end
unselect all files
# File lib/cygnus.rb, line 367 def unselect_all $selected_files = [] $visual_mode = nil end
# File lib/cygnus.rb, line 867 def views views=%w[/ om oa Om OL oL On on] viewlabels=%w[Dirs Newest Accessed Oldest Largest Smallest Reverse Name] $sorto = views[$viewctr] $title = viewlabels[$viewctr] $viewctr += 1 $viewctr = 0 if $viewctr > views.size $files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}M)'`.split("\n") end
# File lib/cygnus.rb, line 1178 def viminfo file = File.expand_path("~/.viminfo") if File.exists? file $title = "Files from ~/.viminfo" #$files = `grep '^>' ~/.viminfo | cut -d ' ' -f 2- | sed "s#~#$HOME#g"`.split("\n") $files = `grep '^>' ~/.viminfo | cut -d ' ' -f 2- `.split("\n") $files.reject! {|x| x = File.expand_path(x); !File.exists?(x) } show_list end end
# File lib/cygnus.rb, line 1293 def visual_block_clear if $visual_block_start star = [$visual_block_start, $cursor].min fin = [$visual_block_start, $cursor].max $selected_files = $selected_files - $view[star..fin] end $visual_block_start = nil $visual_mode = nil end
# File lib/cygnus.rb, line 1286 def visual_mode_toggle $visual_mode = !$visual_mode if $visual_mode $visual_block_start = $cursor $selected_files.push $view[$cursor] end end
# File lib/cygnus.rb, line 1188 def z_interface file = File.expand_path("~/.z") if File.exists? file $title = "Directories from ~/.z" $files = `sort -rn -k2 -t '|' ~/.z | cut -f1 -d '|'`.split("\n") home = ENV['HOME'] $files.collect! do |f| f.sub(/#{home}/,"~") end show_list end end