Permalink
Browse files

MrT is a curses file finder.

  • Loading branch information...
vic committed Mar 17, 2011
0 parents commit 645843280c187ad98de722816d162c968324b048
Showing with 159 additions and 0 deletions.
  1. +18 −0 README.md
  2. +141 −0 bin/mrT
@@ -0,0 +1,18 @@
+Mr T
+====
+
+Textmate-like file finder on a curses interface. Intended for file completion on
+shell prompt.
+
+Mr T requires a ruby compiled with curses devel, it also makes use of the ruby
+extension provided by (Command-T)[https://wincent.com/products/command-t]
+
+
+== Basic Usage
+
+ mrT [basedir]
+
+== TODO
+
+Instructions on how to setup as bash file completion mechanism.
+
141 bin/mrT
@@ -0,0 +1,141 @@
+#!/usr/bin/env ruby
+
+# TODO: make command-t a reusable gem!
+$LOAD_PATH.unshift File.expand_path('~/.vim/bundle/command-t/ruby')
+
+require 'curses'
+require 'command-t/finder'
+
+class BashT
+
+ attr_reader :str, :shown_from, :pwd
+
+ def initialize(pwd)
+ @str = []
+ @options = {
+ }
+ @pwd = pwd
+ @finder = CommandT::Finder.new @pwd, @options
+ end
+
+ def run
+ value = with_curses { interact }
+ File.expand_path(value, @pwd) if value
+ end
+
+ def with_curses
+ Curses.init_screen
+ Curses.nonl
+ Curses.cbreak
+ Curses.noecho
+
+ @screen = Curses.stdscr
+ @screen.scrollok true
+ @screen.keypad true
+
+ begin
+ value = yield
+ rescue Interrupt
+ Curses.close_screen
+ ensure
+ Curses.close_screen
+ end
+ end
+
+ def interact
+ catch :done do
+ filter
+ while true
+ Curses.setpos(0,0)
+ @screen.clrtoeol
+ Curses.addstr('>> ')
+ Curses.addstr(str.join)
+ @screen.refresh
+ c = Curses.getch
+ case c
+ when 27 # ESCAPE
+ throw :done
+ when Curses::KEY_ENTER, 13
+ throw :done, @matches[@selected]
+ when Curses::KEY_RIGHT, 9 # TAB
+ item_incr(10)
+ when Curses::KEY_LEFT, 353 # SHIT-TAB
+ item_incr(-10)
+ when Curses::KEY_UP, Curses::KEY_CTRL_P
+ item_incr(-1)
+ when Curses::KEY_DOWN, Curses::KEY_CTRL_N
+ item_incr(1)
+ when Curses::KEY_NPAGE
+ item_incr(page_size)
+ when Curses::KEY_PPAGE
+ item_incr(-page_size)
+ when Curses::KEY_BACKSPACE
+ str.pop
+ filter
+ when (0..255)
+ str << c.chr
+ filter
+ end
+ end
+ end
+ end
+
+ def shown_to
+ shown_from + page_size
+ end
+
+ def page_size
+ @screen.maxy - 2
+ end
+
+ def row(index = @selected)
+ index - shown_from + 1
+ end
+
+ def select(index)
+ render_item
+ if index > shown_to
+ render(index - shown_to + shown_from)
+ elsif index < shown_from
+ render(index)
+ end
+ @selected = index
+ render_item index, true
+ end
+
+ def item_incr(incr)
+ index = @selected + incr
+ index = 0 if index < 0
+ index = @matches.size - 1 unless index < @matches.size
+ select index
+ end
+
+ def render_item(index = @selected, standout = false)
+ Curses.setpos(row(index) , 0)
+ @screen.clrtoeol
+ Curses.standout if standout
+ Curses.addstr @matches[index]
+ Curses.standend if standout
+ end
+
+ def render(from = 0)
+ @shown_from = from
+ (0..page_size).map { |y| render_item y + from }
+ end
+
+ def filter
+ pattern = str.join
+ @selected = 0
+ @matches = @finder.sorted_matches_for pattern
+ render @selected
+ render_item @selected, true
+ end
+
+end
+
+if $0 == __FILE__
+ dir = Dir.pwd
+ dir = ARGV.first if ARGV.first && File.directory?(ARGV.first)
+ res = BashT.new(dir).run
+ puts res if res
+end

0 comments on commit 6458432

Please sign in to comment.