madx / jumpr

like autojump and friends, in ruby + yaml

This URL has Read+Write access

madx (author)
Fri Jun 19 08:41:52 -0700 2009
commit  195e9f84403c296b53c8231fc4572be45e71a3b6
tree    b1a8236d3d4a944674d4fdfb61e4d9e94fbc2aa8
parent  8077c358e8adda030423b97df5f38bfe878012a7
jumpr / jumpr
100755 116 lines (94 sloc) 2.514 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env ruby
require 'yaml'
 
HELP = <<-EOH
*j* [*-@*_mark_|_mark_|*--list*|*--help*]
*j* *@*_mark_ _path_
 
Bookmark your favorite directories.
 
--list: list your current available marks.
--help: show this help message.
*j* _mark_: jumps to a mark.
*j* *@*_mark_ _path_: add a mark to path (path will be expanded).
*j* *-@*_mark_: remove a mark.
 
Marks must be composed of alphanumerical characters and underscores/dashes.
 
When you jump to a mark, you can append a trailing folder like this:
*j* _mark_/foo
and j will append foo to the resolved mark.
 
This program is WTFPL-licensed, see the LICENSE file distributed with it.
EOH
 
HELP.gsub! /(_|\*)([@a-z_-]+)(?:_|\*)/ do
  [$~[1][0..0].eql?("*") ? "\e[1m" : "\e[4m" , $~[2], "\e[0m"].join('')
end
 
MARKS = File.expand_path("~/.jumprc")
 
class Jumpr
  class << self
    def load(file)
      @rc = file
      @marks = YAML.load(File.read(file)) || {}
    end
 
    def add(mark, target)
      @marks[mark] = File.expand_path(target)
      dump
    end
 
    def remove(mark)
      if @marks.delete(mark)
        dump
        puts "Deleted mark #{mark}"
      else
        puts "No such mark #{mark}"
      end
    end
 
    def jump(expr, rest="")
      expr = Regexp.new(expr, Regexp::IGNORECASE)
      matches = @marks.select {|k,v| k =~ expr }
      if matches.size.zero?
        puts "No matches."
      elsif matches.size == 1
        puts File.join(matches.first.last, *rest)
        exit 0
      else
        puts "Multiple matches:"
        list_matches(matches)
      end
    end
 
    def list
      list_matches(@marks)
    end
 
    private
    def dump
      File.open(@rc, "w+") {|f| f.write YAML.dump(@marks) }
    end
 
    def list_matches(matches)
      matches.each do |mark,target|
        puts "#{mark}: #{target}"
      end
    end
  end
end
 
begin
  File.open(MARKS, "w+") {|f| f.write "--- {}"} unless File.exist? MARKS
  Jumpr.load(MARKS)
 
  if ARGV[0] && mark = ARGV[0].dup
    case mark
      when /^@(?:(?:\w|[_-])+)$/
        target = ARGV[1] || "."
        mark.slice!(0)
        Jumpr.add(mark, target)
        puts "Added #{File.expand_path(target)} as #{mark}"
 
      when /^-@.+/
        mark.slice!(0..1)
        Jumpr.remove(mark)
 
      when /^--list$/
        Jumpr.list
 
      when /^--help$/
        puts HELP
 
      else
        mark, *rest = mark.split("/")
        Jumpr.jump(mark, rest)
    end
  else
    raise ArgumentError, HELP.lines.to_a[0..1]
  end
rescue => e
  puts e.message
end
exit 1