summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2009-05-09 00:00:00 +0200
committerhut <hut@lavabit.com>2009-05-09 00:00:00 +0200
commita0de7f95bc7525b99b2c2e16f566e0ee367e9c3c (patch)
tree62d1cdf9523f4e8fad28ca7df0e1d696c991d2db
parent34bfb32ecf2cea5e5de95980beedb681139d9c01 (diff)
lots of changes. version 0.2.1v0.2.1
-rw-r--r--ChangeLog46
-rw-r--r--Readme0
-rw-r--r--code/action.rb69
-rw-r--r--code/bars.rb134
-rw-r--r--code/debug.rb24
-rw-r--r--code/directory.rb (renamed from code/extensions.rb)381
-rw-r--r--code/draw.rb194
-rw-r--r--code/extensions/basic.rb149
-rw-r--r--code/extensions/fileutils.rb1726
-rw-r--r--code/fm.rb57
-rw-r--r--code/keys.rb238
-rw-r--r--code/screensaver/clock.rb10
-rw-r--r--code/types.rb106
-rwxr-xr-xdata/generate.rb21
-rw-r--r--data/mime.datbin0 -> 10452 bytes
-rw-r--r--data/mime.types769
-rwxr-xr-xfm35
-rw-r--r--interface/ncurses.rb110
18 files changed, 3562 insertions, 507 deletions
diff --git a/ChangeLog b/ChangeLog
index 375565f6..6c2edddd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,14 +1,54 @@
+Version 0.2.1
+
+2009-05-09 hut
+ Oh no. I neglegted to write change logs... in a nutshell, i changed:
+ New Hotkey: [r]...flags...[r] which runs the selected file with flags
+ like [d] to detach the process or [t] to run it in a seperate terminal
+ For that I also changed Action.run()
+
+2009-04-27 hut
+ Minor changes to the way directories and file infos are read
+ entries are not instantly scheduled upon encounter
+ Rewritten "ascend" method, which uses Action::run() now (still theres a lot
+ to be done)
+ Directory::entry#mimetype() instead of Fm.MIMETYPES[Directory::entry#ext()]
+
+2009-04-18 hut
+ Found reproducable bug which leaves it (after closing) running and using up
+ 99% CPU. It happens when the window managers way of closing windows by
+ pressing the X button or pressing Alt+F4 is used to quit.
+ New Hotkeys: [S-TAB] is a shortcut for [`][`] and [TAB] for [`][9]
+ Better distinguishable columns
+ MIME support, allowing sorting by MIME-filetype
+ TODO: fall back to sorting by name for two files of identical filetype
+ Sorting by extension
+ Minor bugs fixed
+
+2009-04-16 hut
+ New Combination [c][u][t] to mark files for moving
+ Replaced system() calls with cp or mv with the use of FileUtils
+ Modified FileUtils for showing its progress the progressbar
+ Fixed threading problem which made it impossible to stop copying/moving
+ Fixed priority problems, fluent UI while copying.
+
+ TODO: enqueue file operations for better performance
+
+2009-04-15 hut
+
+ Added possibility to run fm with a filename in argument which runs the
+ file, like an enter-press inside fm would run it.
+
Version 0.2
2009-04-10 hut
Generating Previews in the background
- Help screen
- Tooltips for (S) and (t)
+ Help screen with [?]
+ Tooltips for [S] and [t]
Added more filetype associations
Split up fm.rb into several files
2009-04-09 hut
- New Hotkey (S) to change sorting order
+ New Hotkey [S] to change sorting order
Generalized file-modifying tasks in the Action module
2009-04-08 hut
diff --git a/Readme b/Readme
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/Readme
diff --git a/code/action.rb b/code/action.rb
new file mode 100644
index 00000000..e463e852
--- /dev/null
+++ b/code/action.rb
@@ -0,0 +1,69 @@
+module Action
+ def self.copy(files, path)
+ files = [files] unless files.is_a? Array
+ unless files.empty?
+ CopyBar2.new(files, path)
+ end
+ end
+
+ def self.move(files, path)
+ files = [files] unless files.is_a? Array
+ unless files.empty?
+ MoveBar2.new(files, path)
+ end
+ end
+
+ def self.run(hash = {})
+ unless OpenStruct === hash
+ hash = OpenStruct.new(hash)
+ end
+
+ cf = Fm.currentfile
+
+ all = hash.all.or true
+ files = hash.files.or(all ? Fm.selection : [cf])
+ mode = hash.mode.or 0
+ newway = hash.newway.or false
+
+ return false if files.nil?
+
+ if newway
+ hash = Fm.filehandler(files, hash)
+ handler = hash.exec
+ else
+ handler, wait = Fm.getfilehandler(*files)
+ end
+
+ return false unless handler
+
+ wait = hash.wait.or wait
+ new_term = hash.new_term.or false
+ detach = hash.detach.or false
+
+ log handler
+ if detach
+ run_detached(handler, new_term)
+ else
+ run_inside(handler, wait)
+ end
+ return true
+ end
+
+ def self.run_detached(what, new_term)
+ if new_term
+ p = fork { exec('x-terminal-emulator', '-e', 'bash', '-c', what) }
+# Process.detach(p)
+ else
+ p = fork { exec "#{what} 2>> /dev/null >> /dev/null" }
+ Process.detach(p)
+ end
+ end
+
+ def self.run_inside(what, wait)
+ closei
+ system(*what)
+ gets if wait
+ starti
+ end
+end
+
diff --git a/code/bars.rb b/code/bars.rb
new file mode 100644
index 00000000..61d14572
--- /dev/null
+++ b/code/bars.rb
@@ -0,0 +1,134 @@
+class Bar
+ def initialize( text = '' )
+ @text = text
+ @text_prefix = nil
+ @max = 0
+ @done = 0
+ @counter = 0
+ @thread = nil
+ @update_proc = nil
+ Fm.bar_add(self)
+ end
+
+ def kill(evil = true)
+ Fm.bar_del(self)
+ Fm.force_update
+
+ @thread.kill
+ end
+
+ def update(&block)
+ if block
+ @update_proc = block
+ elsif @update_proc
+ @update_proc.call(self)
+ end
+ end
+
+ def set_text_prefix(text)
+ @text_prefix = text
+ end
+ def set_text(text)
+ @text_prefix = nil
+ @text = text
+ end
+ alias text= set_text
+
+ attr_accessor :thread, :counter, :max
+end
+
+class CopyBar < Bar
+ def initialize( text = '' )
+ super
+
+ @update_proc = proc do |b|
+ begin
+ b.done = File.size(fname).to_f / finished
+ rescue
+ b.done = 0
+ end
+ end
+ end
+end
+
+class Bar2
+ def kill(evil = true)
+ Fm.bar_del(self)
+ Fm.force_update
+
+ @thread.kill
+ end
+
+ def set_text_prefix(text)
+ @text_prefix = text
+ end
+ def set_text(text)
+ @text_prefix = nil
+ @text = text
+ end
+ alias text= set_text
+
+ attr_accessor :thread, :counter, :max
+ def done
+ if @counter.is_a? MutableNumber
+ @counter.value.to_f / @max
+ else
+ 0
+ end
+ end
+
+ def update() end
+
+ def text
+ if @text_prefix
+ "#{@text_prefix} #{(@counter.value.to_f * 10000/ @max).round.to_f/100}%"
+ elsif @text
+ @text
+ else
+ ""
+ end
+ end
+end
+
+class CopyOrMoveBar < Bar2
+ def initialize(files, path)
+ path = path.path unless path.is_a? String
+ Fm.bar_add(self)
+ log([files, path])
+
+
+ @thread = Thread.new do
+ begin
+ for file in files
+ file = file.path unless file.is_a? String
+ if File.exists?(file)
+ run_operation(file, path)
+ end
+ end
+ rescue
+ log $!
+ log $!.backtrace
+ ensure
+ kill(false)
+ end
+ end
+ @thread.priority = Fm::COPY_PRIORITY
+ end
+end
+
+class CopyBar2 < CopyOrMoveBar
+ def run_operation(file, path)
+ if File.directory?(file)
+ FileUtils.cp_r_in_bar(self, file, path)
+ else
+ FileUtils.cp_in_bar(self, file, path)
+ end
+ end
+end
+
+class MoveBar2 < CopyOrMoveBar
+ def run_operation(file, path)
+ FileUtils.mv_in_bar(self, file, path)
+ end
+end
+
diff --git a/code/debug.rb b/code/debug.rb
index 6261ed0e..d3a97190 100644
--- a/code/debug.rb
+++ b/code/debug.rb
@@ -1,4 +1,3 @@
-
require 'pp'
module Debug
@@ -25,6 +24,28 @@ module Debug
end
if LOG_LEVEL > 0
+ def bm(descr="benchmark", &block)
+ # Benchmark
+ t1 = Time.now
+ yield
+ dur = Time.now-t1
+
+ # substract the durtation of a "bm(..) do end"
+ dur -= bm_dummy(descr) do end
+
+ # Format the duration
+ dur *= 1000
+ dur = dur > 0 ? dur : 0
+ dur = '%0.3f' % dur
+ logerr("#{descr}: #{dur}ms")
+ end
+
+ def bm_dummy(descr="benchmark", &block)
+ t1 = Time.now
+ yield
+ return (Time.now-t1)
+ end
+
def __log__(obj, level)
if level <= LOG_LEVEL
obj = obj.nil? ? "checkpoint at #{Time.now}" : obj
@@ -63,5 +84,6 @@ module Debug
def log(a=nil) end
def logpp(a=nil) end
def trace() end
+ def bm(*args, &block) yield end
end
end
diff --git a/code/extensions.rb b/code/directory.rb
index a15fc952..c42392aa 100644
--- a/code/extensions.rb
+++ b/code/directory.rb
@@ -1,184 +1,6 @@
-class Bar
- def initialize( text = '' )
- @text = text
- @done = 0
- @thread = nil
- @update_proc = nil
- Fm.bar_add(self)
- end
-
- def kill(evil = true)
- Fm.bar_del(self)
- Fm.force_update
-
- @thread.kill
- end
-
- def update(&block)
- if block
- @update_proc = block
- elsif @update_proc
- @update_proc.call(self)
- end
- end
-
- attr_accessor :text, :done, :thread
-end
-
-class CopyBar < Bar
- def initialize( text = '' )
- super
-
- @update_proc = proc do |b|
- begin
- b.done = File.size(fname).to_f / finished
- rescue
- b.done = 0
- end
- end
- end
-end
-
-module Action
-# def self.get_all_files(path)
-# glob = Dir.new(path).to_a
-# end
-
- def self.make_a_bar_for_one(text, command)
- bar = CopyBar.new(test)
-
- finished = File.size(from[0]).to_f
- fname = File.join(to, File.basename(from[0]))
-
- bar.thread = Thread.new do
- begin
- system('ionice', '-c3', command, *(from + [to]))
- ensure
- bar.kill(false)
- end
- end
- end
-
- def self.copy(from, to)
-# log [from, to]
-
-# if String === from[0]
-# from[0] = Directory::Entry.new(from[0])
-# end
-
- if from.size == 1 and from[0].file?
- from = from[0]
- bar = Bar.new("Copying...")
- finished = from.size.to_f
- fname = File.join(to, from.basename)
-
- bar.update do |b|
- begin
- b.done = File.size(fname).to_f / finished
- rescue
- b.done = 0
- end
- end
-
- bar.thread = Thread.new do
- begin
- system('cp', from.to_s, to)
- ensure
- bar.kill(false)
- end
- end
-
- else
- bar = Bar.new("Copying...")
- from = from.dup
- from = [from] unless Array === from
- finished = Dir.number_of_files(*from.map{|x| x.to_s})
- count = 0
-
- bar.update do |b|
- begin
- b.done = count / finished
- rescue
- b.done = 0
- end
- end
-
- from.map!{|x| x.to_s}
- bar.thread = Thread.new do
- begin
- system('cp', '-r', *(from + [to.to_s]))
-# IO.popen("cp -vr #{from.join(' ')} #{to.sh}") do |f|
-# IO.popen(['cp', '-vr', *(from + [to])]) do |f|
-# count += 1 while f.gets =~ /' -> `/
-# end
- ensure
- bar.kill(false)
- end
- end
- end
- end
-
- def self.move(from, to)
-# log [from, to]
-
-# if String === from[0]
-# from[0] = Directory::Entry.new(from[0])
-# end
-
- if from.size == 1 and from[0].file?
- from = from[0]
- bar = Bar.new("Moving...")
- finished = from.size.to_f
- fname = File.join(to, from.basename)
-
- bar.update do |b|
- begin
- b.done = File.size(fname).to_f / finished
- rescue
- b.done = 0
- end
- end
-
- bar.thread = Thread.new do
- begin
- system('mv', from.to_s, to)
- ensure
- bar.kill(false)
- end
- end
-
- else
- bar = Bar.new("Moving...")
- from = from.dup
- from = [from] unless Array === from
- finished = Dir.number_of_files(*from.map{|x| x.to_s})
- count = 0
-
- bar.update do |b|
- begin
- b.done = count / finished
- rescue
- b.done = 0
- end
- end
-
- from.map!{|x| x.to_s}
- bar.thread = Thread.new do
- begin
- system('mv', *(from + [to.to_s]))
-# IO.popen("mv -v #{from.join(' ')} #{to.sh}") do |f|
-# count += 1 while f.gets =~ /' -> `/
-# end
- ensure
- bar.kill(false)
- end
- end
- end
- end
-end
-
class Directory
BAD_TIME = Time.at(0)
+ MOVIE_EXTENSIONS = %w(avi mpg mpeg mp4 mp5 ogv ogm wmv mkv flv fid vob div divx)
class Entry #{{{
# Let's just cache every shit, because i don't want
# to call File methods all the time
@@ -194,6 +16,9 @@ class Directory
@dirname = File.dirname(dirname)
@basename = File.basename(dirname)
end
+ @name, @ext = @basename.split_at_last_dot
+# @ext = @basename.from_last('.') || ''
+ @movie = MOVIE_EXTENSIONS.include?(@ext)
@size = 0
@exists = false
@rights = '----------'
@@ -208,8 +33,10 @@ class Directory
@marked = false
end
- attr_reader(:basename, :mtime, :rights, :type, :path,
- :infostring, :readlink, :basename, :size, :ctime)
+ attr_reader *%w(
+ basename mtime rights type path ext
+ infostring readlink basename size ctime name
+ )
attr_accessor(:marked)
@@ -217,11 +44,19 @@ class Directory
def exists?() @exists end
def marked?() @marked end
def symlink?() @symlink end
+ def movie?() @movie end
def broken_symlink?() @symlink and !@exists end
def dir?() @type == :dir end
def file?() @type == :file end
def writable?() @writable end
def executable?() @executable end
+ def mimetype()
+ if @type == :dir
+ nil
+ else
+ Fm::MIMETYPES[@ext]
+ end
+ end
def delete!
if @type == :dir
@@ -242,17 +77,7 @@ class Directory
end
def sh
- res = @path.dup
- res.gsub!('\\\\', "\000")
- res.gsub!(' ', '\\ ')
- res.gsub!('(', '\\(')
- res.gsub!('&', '\\&')
- res.gsub!(')', '\\)')
- res.gsub!('*', '\\*')
- res.gsub!('\'', '\\\'')
- res.gsub!('"', '\\"')
- res.gsub!("\000", '\\\\')
- return res
+ @path.sh
end
def in? path
@@ -322,6 +147,9 @@ class Directory
@file_size = 0
@pointed_file = nil
@width = 1000
+ @read = false
+ @empty = true
+ @scheduled = false
refresh
end
@@ -334,6 +162,7 @@ class Directory
else
@files.reject!{|x| x[0] == ?. or x == 'lost+found'}
end
+
if @files.empty?
@files = ['.']
end
@@ -342,14 +171,60 @@ class Directory
@files.map!{|basename| Entry.new(@path, basename)}
end
- attr_reader(:path, :files, :pos, :width, :files_raw, :file_size)
+ attr_reader(:path, :files, :pos, :width, :files_raw,
+ :file_size, :read)
+ attr_accessor(:scheduled)
+
+ def scheduled?() @scheduled end
+ def read?() @read end
def pos=(x)
+# if @files.size <= 1 or x < 0
+# x = 0
+# elsif x > @files.size
+# x = @files.size - 1
+# end
@pos = x
+ make_sure_cursor_is_in_range()
@pointed_file = @files[x]
resize
end
+ def recheck_stuff()
+# log "pointed file: #@pointed_file"
+# log @files_raw
+# log ""
+ if test = @files_raw.index(@pointed_file)
+# log("if")
+ @pos = test
+ else
+# log("else")
+ make_sure_cursor_is_in_range()
+ end
+ end
+
+ def make_sure_cursor_is_in_range()
+ if @files.size <= 1 or @pos < 0
+ @pos = 0
+ elsif @pos > @files.size
+ @pos = @files.size - 1
+ end
+ end
+
+ def find_file(x)
+ x = File.basename(x)
+
+ files.each_with_index do |file, i|
+ if file.basename == x
+ self.pos = i
+ end
+ end
+ end
+
+ def empty?()
+ Dir.entries(@path).size <= 2
+ end
+
def restore()
for f in @files
f.marked = false
@@ -389,6 +264,7 @@ class Directory
f.refresh
@file_size += f.size if f.file?
end
+ @read = true
end
# def refresh()
@@ -421,19 +297,29 @@ class Directory
end
def schedule()
+ @scheduled = true
Fm.schedule(self)
end
def refresh!()
+ oldfile = @pointed_file
read_dir
get_file_info
sort
+
+ if @files.include? oldfile
+ self.pointed_file = oldfile
+ end
end
def sort_sub(x, y)
case OPTIONS['sort']
when :name
x.basename <=> y.basename
+ when :ext
+ x.ext <=> y.ext
+ when :type
+ x.ext.filetype <=> y.ext.filetype
when :size
x.size <=> y.size
when :ctime
@@ -462,112 +348,3 @@ class Directory
end
end
-
-class File
- MODES_HASH = {
- '0' => '---',
- '1' => '--x',
- '2' => '-w-',
- '3' => '-wx',
- '4' => 'r--',
- '5' => 'r-x',
- '6' => 'rw-',
- '7' => 'rwx'
- }
- def self.modestr(f)
- unless exists?(f)
- return '----------'
- end
-
- if symlink?(f)
- result = 'l'
- elsif directory?(f)
- result = 'd'
- else
- result = '-'
- end
-
- s = ("%o" % File.stat(f).mode)[-3..-1]
- for m in s.each_char
- result << MODES_HASH[m]
- end
-
- result
- end
-end
-
-class Dir
- def self.number_of_files(*dirs)
- n = 0
- dirs.each do |entry|
- if File.directory?(entry)
- n += 1 + number_of_files(*(Dir.new(entry).to_a - ['.', '..']).map\
- {|x| File.join entry, x } )
- else
- n += 1
- end
- end
- return n
- end
-end
-
-class Numeric
- def limit(max, min = 0)
- self < min ? min : (self > max ? max : self)
- end
-
- def bytes space = true, n_round = 2
- n = 1024
- a = %w(B K M G T Y)
-
- i = 0
- flt = self.to_f
-
- while flt > n and i < a.length - 1
- flt /= n
- i += 1
- end
-
-# flt = flt.round(n_round)
- r = 10 ** n_round
- flt *= r
- flt = flt.round.to_f / r
- int = flt.to_i
- flt = int if int == flt
-
- return flt.to_s + (space ? ' ' + a[i] : a[i])
- end
-end
-
-class Array
- def wrap(n)
- n.times { push shift }
- end
-end
-
-class String
- def clear
- replace String.new
- end
- if RUBY_VERSION < '1.9'
- def ord
- self[0]
- end
- end
-
- def sh
- res = self.dup
- res.gsub!('\\\\', "\000")
- res.gsub!(' ', '\\ ')
- res.gsub!('(', '\\(')
- res.gsub!('&', '\\&')
- res.gsub!(')', '\\)')
- res.gsub!('*', '\\*')
- res.gsub!('\'', '\\\'')
- res.gsub!('"', '\\"')
- res.gsub!("\000", '\\\\')
- return res
- end
-
-end
-
diff --git a/code/draw.rb b/code/draw.rb
index 1a2236cc..dac6c25c 100644
--- a/code/draw.rb
+++ b/code/draw.rb
@@ -1,5 +1,5 @@
module Fm
- DONT_PREVIEW_THESE_FILES = /\.(avi|[mj]pe?g|iso|mp\d|og[gmv]|wm[av]|mkv|torrent|so|class|flv|png|bmp|zip|rar|7z|tar|gz|vob|divx?)$/i
+ DONT_PREVIEW_THESE_FILES = /\.(avi|[mj]pe?g|iso|mp\d|og[gmv]|wm[av]|mkv|torrent|so|class|flv|png|bmp|vob|divx?)$/i
def self.column_put_file(n, file)
i = 0
@@ -7,85 +7,140 @@ module Fm
m = lines - 2
color 7
bold false
- File.open(file.path, 'r') do |f|
- check = true
- left, wid = get_boundaries(n)
- f.lines.each do |l|
- if check
- check = false
- break unless l.each_char.all? {|x| x[0] > 0 and x[0] < 128}
- end
- puti i+1, left, l.gsub("\t"," ")[0, wid-1].ljust(wid)
+ left, wid = get_boundaries(n)
+ if file.ext =~ /(?:rar|zip|7z|tar|gz)$/ and file.size < 10485760
+ text = `aunpack -l #{file.sh} 2>> /dev/null`
+ text.each_line do |l|
+ puti i+1, left, l[0, wid-1].ljust(wid)
i += 1
break if i == m
end
+ else
+ File.open(file.path, 'r') do |f|
+ check = true
+ left, wid = get_boundaries(n)
+ f.lines.each do |l|
+ if check
+ check = false
+ break unless l.each_char.all? {|x| x[0] > 0 and x[0] < 128}
+ end
+ puti i+1, left, l.gsub("\t"," ")[0, wid-1].ljust(wid)
+ i += 1
+ break if i == m
+ end
+ end
end
end
column_clear(n, i)
end
def self.put_directory(c, d)
- l = 0
+ l = 1
if d
infos = (c == COLUMNS - 2)
left, wid = get_boundaries(c)
- offset = get_offset(d, lines)
- (lines - 1).times do |l|
- lpo = l + offset
- bg = -1
- break if (f = d.files[lpo]) == nil
-
- dir = false
- if f.symlink?
- bld = true
- if f.broken_symlink?
- clr = [1, bg]
+ if d.read? and not d.empty?
+
+ offset = get_offset(d, lines)
+ (lines - 1).times do |l|
+ lpo = l + offset
+ bg = -1
+ break if (f = d.files[lpo]) == nil
+# log f
+
+ dir = false
+ if f.symlink?
+ bld = true
+ if f.broken_symlink?
+ clr = [1, bg]
+ else
+ clr = [6, bg]
+ end
+ dir = f.dir?
+ elsif f.dir?
+ bld = true
+ dir = true
+ clr = [4, bg]
+ elsif f.movie?
+ bld = true
+ clr = [5, bg]
+ elsif f.executable?
+ bld = true
+ clr = [2, bg]
else
- clr = [6, bg]
+ bld = false
+ clr = [7, bg]
end
- dir = f.dir?
- elsif f.dir?
- bld = true
- dir = true
- clr = [4, bg]
- elsif f.executable?
- bld = true
- clr = [2, bg]
- else
- bld = false
- clr = [7, bg]
- end
- fn = f.basename
- if f.marked?
- fn = "*#{fn}"
- end
- if infos
- myinfo = " #{f.infostring} "
- str = fn[0, wid-1].ljust(wid+1)
- if str.size > myinfo.size
- str[-myinfo.size..-1] = myinfo
- yes = true
+ fn = f.basename
+ if f.marked?
+ fn = "* #{fn}"
+ end
+ if infos
+ myinfo = " #{f.infostring} "
+ str = fn[0, wid-1].ljust(wid+1)
+ if str.size > myinfo.size
+ str[-myinfo.size..-1] = myinfo
+ yes = true
+ else
+ yes = false
+ end
+ puti l+1, left, str
+ if dir and yes
+ args = l+1, left+wid-myinfo.size, myinfo.size, *clr
+ color_bold_at(*args)
+ end
else
- yes = false
+ puti l+1, left, fn[0, wid-1].ljust(wid+1)
end
- puti l+1, left, str
- if dir and yes
- args = l+1, left+wid-myinfo.size, myinfo.size, *clr
- color_bold_at(*args)
+
+ args = l+1, left, fn.size.limit(wid-1), *clr
+
+ if d.pos == lpo
+ if c == COLUMNS - 2
+# puti l+1, left-1, '^'
+# puti l+1, left+args[2], '$'
+
+ args[4] = 0
+# args[1] -= 1
+# if args[2] < 5
+# args[2] = 7
+# else
+# args[2] += 1
+# end
+# color_bold_at(l+1, left-1, 1, 0, 0)
+# color_bold_at(l+1, left+args[2], 1, 0, 0)
+ color_reverse_bold_at(*args)
+
+ # ...
+ args[1] -= 1; args[2] += 2
+ color_bold_at(*args)
+ args[1] += 1; args[2] -= 2
+ color_reverse_bold_at(*args)
+ else
+ color_reverse_at(*args)
+ end
+# if f.marked?
+# args[1] += 1
+# args[2] = 1
+# args[3] = 1
+# color_reverse_at(*args)
+# end
+ else
+ if bld then color_at(*args) else color_at(*args) end
+# if bld then color_bold_at(*args) else color_at(*args) end
end
- else
- puti l+1, left, fn[0, wid-1].ljust(wid+1)
end
+ elsif d.read? and d.empty?
+ puti l, left, 'empty'.ljust(wid+1)
- args = l+1, left, fn.size.limit(wid), *clr
+ elsif not d.read?
+ puti l, left, 'reading...'.ljust(wid+1)
+ d.schedule unless d.scheduled?
+ else
+ puti l, left, 'ERROR'.ljust(wid+1)
- if d.pos == lpo
- color_reverse_at(*args)
- else
- if bld then color_bold_at(*args) else color_at(*args) end
- end
end
end
@@ -140,7 +195,9 @@ module Fm
bold false
@cur_y = get_boundaries(COLUMNS-2)[0]
- if @buffer == '?'
+ if @buffer =~ /^block/
+ screensaver
+ elsif @buffer == '?'
cleari
puti 0, " - - - Help - - -"
puti 2, " h/j/k/l: Movement J/K: fast Movement"
@@ -177,12 +234,22 @@ module Fm
puti 8, " gh: go to ~/"
puti 9, " gt: go to ~/.trash/"
else
+ @pwd.recheck_stuff()
+ cf = currentfile
+
+ if cf and s0 = cf.mimetype
+ puti 0, cols-s0.size, s0
+ end
+
s1 = " "
s2 = "#{@path.last.path}#{"/" unless @path.size == 1}"
- cf = currentfile
s3 = "#{cf ? cf.basename : ''}"
- puti 0, (s1 + s2 + s3).ljust(cols)
+ if s0
+ puti 0, (s1 + s2 + s3).ljust(cols-s0.size)
+ else
+ puti 0, (s1 + s2 + s3).ljust(cols)
+ end
bg = -1
color_at 0, 0, -1, 7, bg
@@ -227,6 +294,7 @@ module Fm
puti btm, "Toggle (h)idden_files (d)irs_first (c)olor (f)ilepreview"
else
# log(@pwd)
+# log "Buffer: #{@buffer}"
puti btm, "#@buffer #{@pwd.file_size.bytes(false)},#{@pwd.size},#{@pwd.pos+1} ".rjust(cols)
more = ''
if cf.symlink?
@@ -255,10 +323,10 @@ module Fm
done = bar.done
c = (done * cols).to_i
unless done == 0
- color_at l, 0, c, 0, 2
+ color_at l, 0, c, 0, 4
end
unless done == cols
- color_at l, c, -1, 0, 3
+ color_at l, c, -1, 0, 6
end
end
end
diff --git a/code/extensions/basic.rb b/code/extensions/basic.rb
new file mode 100644
index 00000000..c822e9f6
--- /dev/null
+++ b/code/extensions/basic.rb
@@ -0,0 +1,149 @@
+# Generic extensions of the language
+
+class MutableNumber
+ attr_accessor :value
+
+ def initialize(n=0)
+ @value = n
+ end
+ def add(n=1) @value += n end
+ def sub(n=1) @value -= n end
+end
+
+class Array
+ def wrap(n)
+ # TODO: this can be done better...
+ n.times { push shift }
+ end
+end
+
+class String
+ def clear
+ self.replace("")
+ end
+
+ if RUBY_VERSION < '1.9'
+ def ord
+ self[0]
+ end
+ end
+
+ def from_first(str)
+ self.include?(str) ? self [ self.index(str) + str.size .. -1 ] : nil
+ end
+
+ def from_last(str)
+ self.include?(str) ? self [ self.rindex(str) + str.size .. -1 ] : nil
+ end
+
+ def split_at_last_dot()
+ if ix = self.rindex('.')
+ return self[0...ix], self[ix+1..-1]
+ else
+ return self, ''
+ end
+ end
+
+ def before_last(str)
+ self.include?(str) ? self [ 0 .. rindex(str) - str.size ] : self
+ end
+
+ def filetype()
+ Fm::MIMETYPES[self] || 'unknown'
+ end
+
+ def sh
+ res = self.dup
+ res.gsub!('\\\\', "\000")
+ res.gsub!(' ', '\\ ')
+ res.gsub!('(', '\\(')
+ res.gsub!('&', '\\\&')
+ res.gsub!(')', '\\)')
+ res.gsub!('*', '\\*')
+ res.gsub!('\'', "\\\\'")
+ res.gsub!('"', '\\"')
+ res.gsub!("\000", '\\\\')
+ return res
+ end
+end
+
+class Numeric
+ def limit(max, min = 0)
+ self < min ? min : (self > max ? max : self)
+ end
+
+ def bytes space = true, n_round = 2
+ n = 1024
+ a = %w(B K M G T Y)
+
+ i = 0
+ flt = self.to_f
+
+ while flt > n and i < a.length - 1
+ flt /= n
+ i += 1
+ end
+
+# flt = flt.round(n_round)
+ r = 10 ** n_round
+ flt *= r
+ flt = flt.round.to_f / r
+ int = flt.to_i
+ flt = int if int == flt
+
+ return flt.to_s + (space ? ' ' + a[i] : a[i])
+ end
+end
+
+class Dir
+ def self.number_of_files(*dirs)
+ n = 0
+ dirs.each do |entry|
+ if File.directory?(entry)
+ n += 1 + number_of_files(*(Dir.new(entry).to_a - ['.', '..']).map\
+ {|x| File.join entry, x } )
+ else
+ n += 1
+ end
+ end
+ ret