diff options
author | hut <hut@lavabit.com> | 2009-07-24 02:10:05 +0200 |
---|---|---|
committer | hut <hut@lavabit.com> | 2009-07-24 02:10:05 +0200 |
commit | cbda44e7ca9d957dd48b231b7d463e89d5081053 (patch) | |
tree | 06ce04b5eaa8ac0c02a186cf2c9bdfdee2155ada | |
parent | 3cd5b440d7d7e4714726fa3a68b9724d1bc6d0bc (diff) | |
download | ranger-cbda44e7ca9d957dd48b231b7d463e89d5081053.tar.gz |
implemented #13 (special keys for quick navigation)
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | code/draw.rb | 2 | ||||
-rw-r--r-- | code/fm.rb | 1 | ||||
-rw-r--r-- | code/help.rb | 4 | ||||
-rw-r--r-- | code/keys.rb | 88 | ||||
-rw-r--r-- | code/search.rb | 141 | ||||
-rwxr-xr-x | ranger | 1 |
7 files changed, 167 insertions, 72 deletions
diff --git a/TODO b/TODO index c33a0571..7ef6cc45 100644 --- a/TODO +++ b/TODO @@ -48,7 +48,7 @@ Features ( ) #9 09/07/17 build an abstract layer for file system operations this would encourage the addition of ftp or ssh protocols (X) #11 09/07/17 specify flags at data/types.rb - ( ) #13 09/07/17 special keys for quick navigation + (X) #13 09/07/17 special keys for quick navigation cycle in a certain order, like creation-time, newest first. ( ) #19 09/07/19 make path clickable ( ) #20 09/07/19 accelerate mouse wheel scrolling after a while diff --git a/code/draw.rb b/code/draw.rb index 6b3acc8b..ef1fd35b 100644 --- a/code/draw.rb +++ b/code/draw.rb @@ -294,6 +294,8 @@ module Fm puti btm, "Toggle (h)idden_files (d)irs_first (f)ilepreview (p)review (w)idebar (c)d (!)confirm" when 'e' puti btm, "Edit (a)pplications file(t)ypes" + when 'f' + puti btm, "Find by (r)egexp (s)ize (h)andler (m)time (c)time" else owner = "#{Etc.getpwuid(cf.stat.uid).name}:#{Etc.getgrgid(cf.stat.gid).name}" attr_set(Color.base) diff --git a/code/fm.rb b/code/fm.rb index 793c118a..edf8b80c 100644 --- a/code/fm.rb +++ b/code/fm.rb @@ -16,6 +16,7 @@ module Fm @buffer = '' @pwd = nil @search_string = '' + @search_reset = true @copy = [] @ignore_until = nil @trash = File.expand_path('~/.trash') diff --git a/code/help.rb b/code/help.rb index c514fc4c..ed452d9b 100644 --- a/code/help.rb +++ b/code/help.rb @@ -125,10 +125,10 @@ module Fm key:f /<expr> Search for a "regular expression" - f<expr> Like / but enters/runs the first non-ambiguous match + fr<expr> Like / but executes the first non-ambiguous match F<expr> Shows only files which match the regular expression. + f<x> Walks through the files in a specific order, defined by <x> n or N goes to the next or previous match. - if you search for nothing, n goes to the newest file. What is a regular expression: A very flexible way of defining patterns in text. By writing diff --git a/code/keys.rb b/code/keys.rb index d35e6107..b7822d19 100644 --- a/code/keys.rb +++ b/code/keys.rb @@ -238,14 +238,10 @@ module Fm end when 'n' - if @search_string.empty? - find_newest - else - search(@search_string, 1) - end + quicksearch(1) when 'N' - search(@search_string, 0, true) + quicksearch(-1) when /^cd(.+)$/ str = $1 @@ -275,11 +271,22 @@ module Fm when /^um(.)$/ @memory.delete($1) - when /^f(.+)$/ + when FIND_KEY_REGEXP + Option.search_method = FIND_PROPERTIES[$1] + search_reset! + quicksearch(1) + + when 'fh' + Option.search_method = :handler + quicksearch(1) + + + when /^f[rf](.+)$/ str = $1 + Option.search_method = :regexp if str =~ /^\s?(.*)(L|;|<cr>|<esc>)$/ @buffer = '' - @search_string = $1 + @search_string = $1 unless $1.empty? press('l') if $2 == ';' or $2 == 'L' else test = hints(str) @@ -297,6 +304,7 @@ module Fm str = $1 if str =~ /^\s?(.*)(L|;|<cr>|<esc>)$/ @buffer = '' + Option.search_method = :regexp @search_string = $1 press 'l' if $2 == ';' or $2 == 'L' @@ -601,7 +609,7 @@ module Fm # and do NOT use spaces or newlines inside a regexp @@key_combinations = %w[ - g y c Z cu + g y c Z cu f ter ta S e ?? ?g ?f ?m ?l ?c ?o ?z ?s o m ` ' go @@ -609,8 +617,8 @@ module Fm um /:[^<]*/ - /[fF/!].*/ - /(r|cw|cm|co|cd|mv|gf).*/ + /[F/!].*/ + /(r|ff|fr|cw|cm|co|cd|mv|gf).*/ /b(l(o(c(k(.*)?)?)?)?)?/ /g(r(e(p(.*)?)?)?)?/ /m(k(d(i(r(.*)?)?)?)?)?/ @@ -669,64 +677,6 @@ module Fm @ignore_until = Time.now + t end - def search(str, offset=0, backwards=false) - begin - rx = Regexp.new(str, Regexp::IGNORECASE) - rescue - return false - end - - ary = @pwd.files_raw.dup - ary.wrap(@pwd.pos + offset) - - ary.reverse! if backwards - - for f in ary - g = File.basename(f) - if g =~ rx - @pwd.pointed_file = f - break - end - end - end - - def find_newest() - newest = nil - for f in @pwd.files - if newest.nil? or newest.ctime < f.ctime - newest = f - end - end - @pwd.pointed_file = newest.path - end - - def hints(str) - begin - rx = Regexp.new(str, Regexp::IGNORECASE) - rescue - return false - end - - ary = @pwd.files_raw.dup - ary.wrap(@pwd.pos) - - n = 0 - pointed = false - for f in ary - g = File.basename(f) - if g =~ rx - unless pointed - log "point at #{f}" - @pwd.pointed_file = f - pointed = true - end - n += 1 - end - end - - return n - end - def self.remember_dir @memory["`"] = @memory["'"] = @pwd.path end diff --git a/code/search.rb b/code/search.rb new file mode 100644 index 00000000..2952f59a --- /dev/null +++ b/code/search.rb @@ -0,0 +1,141 @@ +module Fm + def goto(arg) + if arg.is_a? Directory::Entry + @pwd.pointed_file = arg.path + + elsif arg.is_a? String + @pwd.pointed_file = arg + + elsif arg.is_a? Numeric + @pwd.pos = arg + + else + lograise ArgumentError.new + end + end + + FIND_PROPERTIES = { + 's' => :size, + 'm' => :mtime, + 'c' => :ctime, + } + FIND_KEY_REGEXP = /f([#{ FIND_PROPERTIES.keys.join("") }])/ + + def quicksearch(n) + log Option.search_method + case Option.search_method + when *FIND_PROPERTIES.values + quicksearch_by_property(n, Option.search_method) + when :handler + quicksearch_by_handler(n) + when :regexp + quicksearch_by_regexp(n) + else + raise "Wrong search method!" + end rescue lograise + end + + def quicksearch_by_property(n, property) + sorted = @pwd.files.sort do |a, b| + b.send(property) <=> a.send(property) + end + + if @search_reset + @search_reset = false + else + sorted.wrap(sorted.index(currentfile) + n) + end + + goto(sorted.first) + end + + def quicksearch_by_handler(n) + sorted = @pwd.files.sort do |a, b| + a.handler.to_s <=> b.handler.to_s + end + + goto(sorted.first) + end + + def quicksearch_by_regexp(n) + begin + rx = Regexp.new(@search_string, Regexp::IGNORECASE) + rescue + return false + end + + ary = @pwd.files.dup + ary.wrap(@pwd.pos) + if n < 0 + ary.wrap(1) + ary.reverse! + end + ary.wrap(n.abs) + + for file in ary + if file.basename =~ rx + return goto(file) + end + end + end + + def search_reset! + @search_reset = true + end + + def search_reset(array) + if @search_reset + @search_reset = false + sorted.wrap(sorted.index(currentfile) + n) + end + end + + def search(str, offset=0, backwards=false) + begin + rx = Regexp.new(str, Regexp::IGNORECASE) + rescue + return false + end + + ary = @pwd.files_raw.dup + ary.wrap(@pwd.pos + offset) + + ary.reverse! if backwards + + for f in ary + g = File.basename(f) + if g =~ rx + @pwd.pointed_file = f + break + end + end + end + + def hints(str) + begin + rx = Regexp.new(str, Regexp::IGNORECASE) + rescue + return false + end + + ary = @pwd.files_raw.dup + ary.wrap(@pwd.pos) + + n = 0 + pointed = false + for f in ary + g = File.basename(f) + if g =~ rx + unless pointed + log "point at #{f}" + @pwd.pointed_file = f + pointed = true + end + n += 1 + end + end + + return n + end + +end diff --git a/ranger b/ranger index 99144c62..7f3602d2 100755 --- a/ranger +++ b/ranger @@ -68,6 +68,7 @@ opt = { :confirm => true, :file_preview => true, :preview => true, + :search_method => :ctime, :mouse => true, :mouse_interval => 200, :debug_level => 0, |