1#!/usr/bin/env ruby
2
3# browse --
4# This script generates a directory browser, which lists the working
5# directory and allow you to open files or subdirectories by
6# double-clicking.
7
8require 'tk'
9
10class Browse
11  BROWSE_WIN_COUNTER = TkVariable.new(0)
12
13  def initialize(dir)
14    BROWSE_WIN_COUNTER.value = BROWSE_WIN_COUNTER.to_i + 1
15
16    # create base frame
17    base = TkToplevel.new {
18      minsize(1,1)
19      title('Browse : ' + dir)
20    }
21
22    # Create a scrollbar on the right side of the main window and a listbox
23    # on the left side.
24    list = TkListbox.new(base, 'relief'=>'sunken',
25			 'width'=>20, 'height'=>20, 'setgrid'=>'yes') {|l|
26      TkScrollbar.new(base, 'command'=>proc{|*args| l.yview *args}) {|s|
27	pack('side'=>'right', 'fill'=>'y')
28	l.yscrollcommand(proc{|first,last| s.set(first,last)})
29      }
30
31      pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')
32
33      # Fill the listbox with a list of all the files in the directory (run
34      # the "ls" command to get that information).
35      open("|ls -a #{dir}", 'r'){|fid| fid.readlines}.each{|fname|
36	l.insert('end', fname.chomp)
37      }
38
39    }
40
41    # Set up bindings for the browser.
42    base.bind('Destroy', proc{
43		Browse::BROWSE_WIN_COUNTER.value = \
44		                Browse::BROWSE_WIN_COUNTER.to_i - 1
45	      })
46    base.bind('Control-c', proc{base.destroy})
47    list.bind('Double-Button-1',
48	 proc{TkSelection.get.each{|f| self.browse dir, f}})
49  end
50
51  # The method below is invoked to open a browser on a given file;  if the
52  # file is a directory then another instance of this program is invoked; if
53  # the file is a regular file then the Mx editor is invoked to display
54  # the file.
55  def browse (dir, file)
56    file = dir + File::Separator + file if dir != '.'
57    type = File.ftype(file)
58    if type == 'directory'
59      Browse.new(file)
60    else
61      if type == 'file'
62	if ENV['EDITOR']
63	  system(ENV['EDITOR'] + ' ' + file + ' &')
64	else
65	  system('xedit ' + file + ' &')
66	end
67      else
68	STDOUT.print "\"#{file}\" isn't a directory or regular file"
69      end
70    end
71  end
72
73end
74
75Browse.new(ARGV[0] ? ARGV[0] : '.')
76
77TkRoot.new {
78  withdraw
79  Browse::BROWSE_WIN_COUNTER.trace('w', proc{exit if Browse::BROWSE_WIN_COUNTER.to_i == 0})
80}
81
82Tk.mainloop
83