myterm 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/._repath.rb CHANGED
@@ -2,49 +2,30 @@
2
2
 
3
3
  payload = lambda do
4
4
 
5
- bin_folder="#{`pwd`.strip}/bin"
6
- unless File.directory?(bin_folder)
7
- return {
8
- :message => "not a directory, won't add to PATH: #{bin_folder}"
9
- }
10
- end
5
+ dir = File.expand_path('../bin', __FILE__)
6
+ File.directory?(dir) or return {
7
+ :message => "not a directory, won't add to PATH: #{dir}"
8
+ }
11
9
 
12
10
  path = ENV['PATH']
13
- path_parts = path.split(':')
14
-
15
- if path.include?(bin_folder)
16
- if true or ARGV.include?('-F')
17
- unless path_parts.reject! { |p| p == bin_folder }
18
- return {
19
- :message => "bin folder \"#{bin_folder}\" not found in path \"#{path}\""
20
- }
21
- end
22
- return {
23
- :new_path => ( [bin_folder] + [path_parts] ).join(':'),
24
- :message => "rewriting path to have bin folder at the beginning",
25
- :success => true
26
- }
27
- else
28
- if 0 == path.index(bin_folder)
29
- return {
30
- :message => "bin folder is already at front of PATH",
31
- :success => true
32
- }
33
- else
34
- return {
35
- :message => "bin folder is in path but not at front. use -F to rewrite PATH",
36
- :status => :not_front,
37
- :success => true
38
- }
39
- end
40
- end
41
- else
42
- path_parts.unshift(bin_folder)
43
- return {
44
- :new_path => path_parts.join(':'),
11
+ parts = path.split(':')
12
+ case parts.index(dir)
13
+ when nil
14
+ {
15
+ :new_path => ([dir] + parts).join(':'),
45
16
  :message => "prepending bin folder to the beginning of the PATH.",
46
17
  :success => true
47
18
  }
19
+ when 0
20
+ { :message => "already at front of path: \"#{dir}\"",
21
+ :success => true
22
+ }
23
+ else
24
+ {
25
+ :new_path => ([dir] + parts.reject{ |x| x == path }).join(':'),
26
+ :message => "rewriting path to have bin folder at the beginning",
27
+ :success => true
28
+ }
48
29
  end
49
30
 
50
31
  end.call
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  /.DS_Store
2
2
  /.__tmp.sh
3
3
  /.rvmrc
4
+ /*.gem
data/.repath.sh CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- ruby ./._repath.rb 1> .__tmp.sh
4
- source ./.__tmp.sh
3
+ dir="$( cd "$( dirname "$0" )" && pwd )"
4
+ tmp="$dir/.__tmp.sh"
5
+ ruby "$dir/._repath.rb" 1> "$tmp"
6
+ source "$tmp"
7
+ rm "$tmp"
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+
2
+
3
+ ## for version 0.0.4 -
4
+
5
+ ### 2012-01-20
6
+
7
+ * fix issue with tmux sessions
8
+ * overhaul whitespace & naming conventions
9
+
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- myterm (0.0.1)
4
+ myterm (0.0.3)
5
5
  highline
6
6
  rb-appscript
7
+ rmagick
7
8
 
8
9
  GEM
9
10
  remote: http://rubygems.org/
@@ -13,7 +14,9 @@ GEM
13
14
  highline (1.6.2)
14
15
  linecache19 (0.5.12)
15
16
  ruby_core_source (>= 0.1.4)
17
+ rake (0.9.2.2)
16
18
  rb-appscript (0.6.1)
19
+ rmagick (2.13.1)
17
20
  ruby-debug-base19 (0.11.25)
18
21
  columnize (>= 0.3.1)
19
22
  linecache19 (>= 0.5.11)
@@ -30,4 +33,5 @@ PLATFORMS
30
33
 
31
34
  DEPENDENCIES
32
35
  myterm!
36
+ rake
33
37
  ruby-debug19
data/README.md CHANGED
@@ -13,7 +13,13 @@
13
13
 
14
14
  `myterm` attempts to be as self-documenting as possible. Try `myterm -h` for help.
15
15
 
16
- The most common use case for me personally is something like:
16
+ The most common use case for me personally is usually something like:
17
+
18
+ myterm bg ohai
19
+
20
+ where "ohai" is some label that I want to appear in the background of the iTerm window.
21
+
22
+ More ambitiously, I might do:
17
23
 
18
24
  myterm bg --exec node server.js
19
25
 
@@ -26,9 +32,12 @@ which will display the string "node server.js" up in the background and then run
26
32
 
27
33
  `myterm` needs ImageMagick and its `convert` executable to be in your path.
28
34
 
35
+ Installing ImageMagick on your mac is "easy" with macports, provided that you don't run into hiccups. (But be prepared for it to take something like5 minutes.)
36
+
29
37
  `myterm` needs some font file to use. It has an installer that will try to grab the [Simple Life](http://www.dafont.com/simple-life.font) font by Michael Strobel.
30
38
 
31
- Additionally it needs whatever its gem dependencie(s) are, which at the time of this writing are: rb-appscript, highline.
39
+ Additionally it needs whatever its gem dependencie(s) are (which at the time of this writing are: rb-appscript, highline, rmagick). Installing the myterm ruby gem should install these dependencies. If you are developing myterm you could also install them with "bundle install".
40
+
32
41
 
33
42
 
34
43
 
@@ -40,8 +49,9 @@ Additionally it needs whatever its gem dependencie(s) are, which at the time of
40
49
 
41
50
  mkdir ~/src; cd ~/src
42
51
  git clone git@github.com:hipe/myterm.git; cd myterm
43
- gem build *.gemspec
44
- gem install *.gem
52
+ gem build myterm.gemspec
53
+ gem install myterm-VERSION.gem # where VERSION is whatever version was built.
54
+
45
55
 
46
56
 
47
57
  ## Support
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.4
data/lib/myterm/api.rb CHANGED
@@ -1,189 +1,208 @@
1
1
  module Skylab; end
2
- module Skylab::Myterm; end
3
2
 
4
- class Skylab::Myterm::ValidationError < RuntimeError ; end
3
+ module Skylab::Myterm
5
4
 
6
- module Skylab::Myterm::Color
7
- Myterm = Skylab::Myterm
8
- def self.[] obj
9
- obj.extend self
10
- end
11
- def self.dup color
12
- self[color.dup]
13
- end
14
- def alpha= mixed
15
- if mixed.kind_of?(String)
16
- md = /\A(\d+(?:\.\d+)?)%?\z/.match(mixed) or
17
- raise Myterm::ValidationError.new("invalid format for percent #{val.inspect} -- expecting e.g. \"58%\"")
18
- mixed = md[1].to_f
19
- end
20
- (0.0..100.0).include?(mixed) or
21
- raise Myterm::ValidationError.new("Percent value (#{mixed}%) must be between 0 and 100 inclusive.")
22
- self[3] = Myterm::ChannelScalarNormalized[mixed / 100.0]
5
+ class ValidationError < RuntimeError ; end
6
+
7
+ module Color
8
+ def alpha= mixed
9
+ if mixed.kind_of?(String)
10
+ md = /\A(\d+(?:\.\d+)?)%?\z/.match(mixed) or
11
+ raise ValidationError.new("invalid format for percent #{val.inspect} -- expecting e.g. \"58%\"")
12
+ mixed = md[1].to_f
13
+ end
14
+ (0.0..100.0).include?(mixed) or
15
+ raise ValidationError.new("Percent value (#{mixed}%) must be between 0 and 100 inclusive.")
16
+ self[3] = ChannelScalarNormalized[mixed / 100.0]
17
+ end
18
+
19
+ def to_hex
20
+ '#' + self.map{ |x| int_to_hex(x) }.join('')
21
+ end
22
+
23
+ TARGET_PLACES = 2 # each component of an #rrggbb hexadecimal color has 2 places
24
+
25
+ DIVISOR = 16 ** TARGET_PLACES
26
+
27
+ def int_to_hex int
28
+ int.respond_to?(:to_hex) and return int.to_hex
29
+ (int.to_f / DIVISOR).round.to_s(16).rjust(TARGET_PLACES, '0')
30
+ end
23
31
  end
24
- def to_hex
25
- '#' + self.map{ |x| int_to_hex(x) }.join('')
32
+
33
+ class << Color
34
+ def [] obj
35
+ obj.extend self
36
+ end
37
+
38
+ def dup color
39
+ self[color.dup]
40
+ end
26
41
  end
27
- TargetPlaces = 2 # each component of an #rrggbb hexadecimal color has 2 places
28
- Divisor = 16 ** TargetPlaces
29
- def int_to_hex int
30
- int.respond_to?(:to_hex) and return int.to_hex
31
- (int.to_f / Divisor).round.to_s(16).rjust(TargetPlaces, '0')
42
+
43
+ module ChannelScalarNormalized
44
+ def to_hex
45
+ (('ff'.to_i(16).to_f * self).to_i).to_s(16).rjust(2, '0')
46
+ end
32
47
  end
33
- end
34
48
 
35
- module Skylab::Myterm::ChannelScalarNormalized
36
- def self.[] obj
37
- obj.extend self
49
+ class << ChannelScalarNormalized
50
+ def [] obj
51
+ obj.extend self
52
+ end
38
53
  end
39
- def to_hex
40
- (('ff'.to_i(16).to_f * self).to_i).to_s(16).rjust(2, '0')
54
+
55
+ class ImageBuilder
56
+ def build_text_drawing img
57
+ @lines.empty? and return fail("foo")
58
+ #@todo setters for everything etc
59
+ draw = Magick::Draw.new
60
+ draw.gravity = @opts[:gravity] || Magick::NorthEastGravity
61
+ @opts[:fill] ||= '#662020'
62
+ @opts[:fill].kind_of?(Proc) and @opts[:fill] = @opts[:fill].call(self)
63
+ draw.fill = @opts[:fill]
64
+ draw.font = @opts[:font] || "#{ENV['HOME']}/.fonts/SimpleLife.ttf"
65
+ draw.font_style = @opts[:font_style] || Magick::NormalStyle
66
+ draw.pointsize = @opts[:point_size] || 60
67
+ draw.text_antialias = @opts.key?(:text_antialias) ? @opts[:text_antialias] : true
68
+ draw.annotate(img, 0,0,20,10, @lines.first)
69
+ if @lines.length > 1
70
+ second_line = @lines[1..-1].join(' ')
71
+ draw.annotate(img, 0,0,20,80, second_line) do
72
+ self.pointsize = 30
73
+ end
74
+ end
75
+ nil # draw not needed at this point
76
+ end
77
+ private :build_text_drawing
78
+
79
+ def initialize iterm, lines, opts
80
+ @iterm, @lines, @opts = [iterm, lines, opts]
81
+ end
82
+
83
+ attr_reader :iterm
84
+
85
+ def run
86
+ require 'RMagick'
87
+ bg_color = Color.dup(@iterm.session.background_color)
88
+ @opts.key?(:alpha_percent) and bg_color.alpha = @opts[:alpha_percent]
89
+ img = Magick::Image.new(500, 300) do # copying over hard-coded dimensions from original Dmytro script
90
+ self.background_color = bg_color.to_hex
91
+ end
92
+ build_text_drawing img
93
+ img
94
+ end
41
95
  end
42
- end
43
96
 
44
- class Skylab::Myterm::ImageBuilder
45
- Myterm = Skylab::Myterm
46
- class << self
97
+ class << ImageBuilder
47
98
  def build_background_image iterm, lines, opts
48
99
  new(iterm, lines, opts).run
49
100
  end
50
101
  end
51
- def initialize iterm, lines, opts
52
- @iterm, @lines, @opts = [iterm, lines, opts]
53
- end
54
- attr_reader :iterm
55
- def run
56
- require 'RMagick'
57
- bg_color = Myterm::Color.dup(@iterm.session.background_color)
58
- @opts.key?(:alpha_percent) and bg_color.alpha = @opts[:alpha_percent]
59
- img = Magick::Image.new(500, 300) do # copying over hard-coded dimensions from original Dmytro script
60
- self.background_color = bg_color.to_hex
61
- end
62
- build_text_drawing img
63
- img
64
- end
65
- private
66
- def build_text_drawing img
67
- @lines.empty? and return fail("foo")
68
- #@todo setters for everything etc
69
- draw = Magick::Draw.new
70
- draw.gravity = @opts[:gravity] || Magick::NorthEastGravity
71
- @opts[:fill] ||= '#662020'
72
- @opts[:fill].kind_of?(Proc) and @opts[:fill] = @opts[:fill].call(self)
73
- draw.fill = @opts[:fill]
74
- draw.font = @opts[:font] || "#{ENV['HOME']}/.fonts/SimpleLife.ttf"
75
- draw.font_style = @opts[:font_style] || Magick::NormalStyle
76
- draw.pointsize = @opts[:point_size] || 60
77
- draw.text_antialias = @opts.key?(:text_antialias) ? @opts[:text_antialias] : true
78
- draw.annotate(img, 0,0,20,10, @lines.first)
79
- if @lines.length > 1
80
- second_line = @lines[1..-1].join(' ')
81
- draw.annotate(img, 0,0,20,80, second_line) do
82
- self.pointsize = 30
83
- end
84
- end
85
- nil # draw not needed at this point
86
- end
87
- end
88
102
 
89
- class Skylab::Myterm::ItermProxy
90
- # ItermProxy is a wrapper around everything Iterm to the extent that its AppleScript interface supports
103
+ class ItermProxy
104
+ # ItermProxy is a wrapper around everything Iterm to the extent that its AppleScript interface supports
105
+ #
106
+ MIN_LEN = 50
91
107
 
92
- Myterm = ::Skylab::Myterm # keep top level name out of the bulk of the code
108
+ def app
109
+ @app ||= begin
110
+ require 'appscript'
111
+ Appscript.app('iTerm')
112
+ end
113
+ end
114
+ private :app
93
115
 
94
- MinLen = 50
116
+ def invalid msg
117
+ raise ValidationError.new(msg)
118
+ end
119
+ private :invalid
95
120
 
96
- def bounds= arr
97
- x = arr.detect { |i| i.to_s !~ /^\d+$/ } and return invalid("expecting digit had #{x.inspect}")
98
- x = arr[2,2].detect { |i| i.to_i < MinLen } and return invalid("too small: #{x} (min: #{MinLen})")
99
- app.windows[0].bounds.set arr
100
- end
121
+ def bounds= arr
122
+ x = arr.detect { |i| i.to_s !~ /^\d+$/ } and return invalid("expecting digit had #{x.inspect}")
123
+ x = arr[2,2].detect { |i| i.to_i < MIN_LEN } and return invalid("too small: #{x} (min: #{MIN_LEN})")
124
+ app.windows[0].bounds.set arr
125
+ end
101
126
 
102
- def bounds
103
- app.windows[0].bounds.get
104
- end
127
+ def bounds
128
+ app.windows[0].bounds.get
129
+ end
105
130
 
106
- def session
107
- tty = `tty`.strip
108
- @session ||= begin
109
- session = catch(:catch_two) do
110
- app.terminals.get.each do |term|
111
- sessions = term.sessions.get
112
- sessions.each do |session|
113
- if session.tty.get == tty
114
- throw :catch_two, session
131
+ def session
132
+ @session ||= begin
133
+ tty = `tty`.strip
134
+ t = s = 0
135
+ catch(:break) do
136
+ (1..app.terminals.count).each do |i|
137
+ (1..app.terminals[i].sessions.count).each do |j|
138
+ if tty == app.terminals[i].sessions[j].tty.get
139
+ throw(:break, SessionProxy.new(app, i, j))
140
+ end
115
141
  end
116
142
  end
117
- end
143
+ nil
144
+ end or fail("couldn't ascertain current session!")
118
145
  end
119
- session or fail("couldn't ascertain current session!")
120
- SessionProxy.new(session)
121
146
  end
122
147
  end
123
148
 
124
- private
125
-
126
- def app
127
- @app ||= begin
128
- require 'appscript'
129
- Appscript.app('iTerm')
149
+ module AppscriptDelegator
150
+ def delegated_attr_readers *list
151
+ list.each do |property|
152
+ lambda do |_property|
153
+ define_method(_property) do
154
+ resource.send(_property).get
155
+ end
156
+ end.call(property)
157
+ end
130
158
  end
131
- end
132
159
 
133
- def invalid msg
134
- raise Myterm::ValidationError.new(msg)
135
- end
136
- end
160
+ def delegated_attr_writers *list
161
+ list.each do |property|
162
+ lambda do |_property|
163
+ define_method("#{_property}=") do |val|
164
+ resource.send(_property).set val
165
+ end
166
+ end.call(property)
167
+ end
168
+ end
137
169
 
138
- module Skylab::Myterm::AppscriptDelegator
139
- def delegated_attr_readers *list
140
- list.each do |property|
141
- lambda do |_property|
142
- define_method(_property) do
143
- @resource.send(_property).get
144
- end
145
- end.call(property)
170
+ def delegated_attr_accessors *list
171
+ delegated_attr_readers(*list)
172
+ delegated_attr_writers(*list)
146
173
  end
147
174
  end
148
- def delegated_attr_writers *list
149
- list.each do |property|
150
- lambda do |_property|
151
- define_method("#{_property}=") do |val|
152
- @resource.send(_property).set val
153
- end
154
- end.call(property)
175
+
176
+ class ItermProxy::SessionProxy
177
+ extend AppscriptDelegator
178
+
179
+ delegated_attr_accessors :background_image_path
180
+
181
+ def background_color
182
+ Color[resource.background_color.get]
155
183
  end
156
- end
157
- def delegated_attr_accessors *list
158
- delegated_attr_readers(*list)
159
- delegated_attr_writers(*list)
160
- end
161
- end
162
184
 
163
- class Skylab::Myterm::ItermProxy::SessionProxy
164
- Myterm = Skylab::Myterm
165
- def initialize session
166
- @resource = session
167
- end
168
- extend Myterm::AppscriptDelegator
185
+ def foreground_color
186
+ Color[resource.foreground_color.get]
187
+ end
169
188
 
170
- delegated_attr_accessors :background_image_path
171
- delegated_attr_readers :tty
189
+ def initialize app, term_idx, session_idx
190
+ @app, @term_idx, @sessions_idx = [app, term_idx, session_idx]
191
+ end
172
192
 
173
- def background_color
174
- Myterm::Color[@resource.background_color.get]
175
- end
193
+ def resource
194
+ @app.terminals[@term_idx].sessions[@sessions_idx]
195
+ end
176
196
 
177
- def foreground_color
178
- Myterm::Color[@resource.foreground_color.get]
197
+ delegated_attr_readers :tty
179
198
  end
180
199
  end
181
200
 
182
- module Skylab::Myterm::ChannelScalarNormalized
183
- def self.[] obj
184
- obj.extend self
185
- end
186
- def to_hex
187
- (('ff'.to_i(16).to_f * self).to_i).to_s(16).rjust(2, '0')
201
+ module Skylab
202
+ class << Myterm
203
+ def version
204
+ File.read(File.expand_path('../../../VERSION', __FILE__))
205
+ end
188
206
  end
189
207
  end
208
+
data/lib/myterm/cli.rb CHANGED
@@ -1,149 +1,144 @@
1
- require "#{File.expand_path('../vendor/face/cli', __FILE__)}"
2
- require "#{File.dirname(__FILE__)}/api"
3
- require 'ruby-debug'
1
+ require File.expand_path('../vendor/skylab/face/cli', __FILE__)
2
+ require File.expand_path('../api', __FILE__)
4
3
  require 'open3'
5
4
 
6
- module Skylab; end
7
- module Skylab::Myterm; end
8
5
 
9
- module Skylab::Myterm::PathPrettifier
10
- HomeDirRe = /\A#{Regexp.escape(ENV['HOME'])}/
11
- protected
12
- def pretty_path path
13
- path.sub(HomeDirRe, '~')
6
+ module Skylab::Myterm
7
+ module PathPrettifier
8
+ HOME_DIR_RE = /\A#{Regexp.escape(ENV['HOME'])}/
9
+ def pretty_path path
10
+ path.sub(HOME_DIR_RE, '~')
11
+ end
14
12
  end
15
- end
16
13
 
17
- class Tmx::Face::Command
18
- include Skylab::Myterm::PathPrettifier
19
- end
14
+ class ::Skylab::Face::Command
15
+ include PathPrettifier # eew
16
+ end
20
17
 
21
- class Skylab::Myterm::Cli < Tmx::Face::Cli
22
- Myterm = ::Skylab::Myterm # don't use fully qualified name internally
23
- include Myterm::PathPrettifier
18
+ class Cli < ::Skylab::Face::Cli
19
+ include PathPrettifier
24
20
 
25
- version do
26
- require "#{File.dirname(__FILE__)}/version"
27
- Myterm::VERSION
28
- end
21
+ version { ::Skylab::Myterm.version }
29
22
 
30
- o(:bounds) do |o|
31
- syntax "#{path} [x y width height]"
32
- o.banner = "gets/sets the bounds of the terminal window\n#{usage_string}"
33
- end
23
+ o(:bounds) do |o|
24
+ syntax "#{invocation_string} [x y width height]"
25
+ o.banner = "gets/sets the bounds of the terminal window\n#{usage_string}"
26
+ end
34
27
 
35
- def bounds o, *a
36
- case a.length
37
- when 4
38
- begin ; iterm.bounds = a ; rescue Myterm::ValidationError => e ; return usage e ; end
39
- when 0
40
- @err.puts iterm.bounds.inspect
41
- else
42
- return usage("bad number of args #{a.length}: expecting 0 or 4")
28
+ def bounds o, *a
29
+ case a.length
30
+ when 4
31
+ begin ; iterm.bounds = a ; rescue ValidationError => e ; return usage e ; end
32
+ when 0
33
+ @err.puts iterm.bounds.inspect
34
+ else
35
+ return usage("bad number of args #{a.length}: expecting 0 or 4")
36
+ end
43
37
  end
44
- end
45
38
 
46
- o(:'bg') do |o, req|
47
- syntax "#{path} [opts] [<text> [<text> [...]]]"
48
- o.banner = "Generate a background image with certain text for the terminal\n#{usage_string}"
49
- o.on('-e', '--exec <cmd ...>', 'Execute <cmd ...> in shell, also use it as text for background.') { }
50
- o.on('-o', '--opacity PERCENT', "Percent by which to make image background opaque",
51
- "(0%: tranparent. 100%: solid. Default: solid)") { |amt| req[:alpha_percent] = amt }
52
- req[:font_file] = DefaultFontFile
53
- o.on('--font FONTFILE.ttf', "font to use (default: #{pretty_path(req[:font_file])})") do |path|
54
- req[:font_file] = path
39
+ o(:'bg') do |o, req|
40
+ syntax "#{invocation_string} [opts] [<text> [<text> [...]]]"
41
+ o.banner = "Generate a background image with certain text for the terminal\n#{usage_string}"
42
+ o.on('-e', '--exec <cmd ...>', 'Execute <cmd ...> in shell, also use it as text for background.') { }
43
+ o.on('-o', '--opacity PERCENT', "Percent by which to make image background opaque",
44
+ "(0%: tranparent. 100%: solid. Default: solid)") { |amt| req[:alpha_percent] = amt }
45
+ req[:font_file] = DEFAULT_FONT_FILE
46
+ o.on('--font FONTFILE.ttf', "font to use (default: #{pretty_path(req[:font_file])})") do |path|
47
+ req[:font_file] = path
48
+ end
49
+ req[:fill] = '#662020'
50
+ o.on('--fill[=COLOR]', "Write text in this color (default: #{req[:fill].inspect})",
51
+ "(when present but with no value, will use \"Text/Normal\" setting of current iTerm tab)" ) do |v|
52
+ req[:fill] = v || lambda { |img| img.iterm.session.foreground_color.to_hex }
53
+ end
54
+ o.on('-v', '--verbose', 'Be verbose.') { req[:verbose] = true }
55
55
  end
56
- req[:fill] = '#662020'
57
- o.on('--fill[=COLOR]', "Write text in this color (default: #{req[:fill].inspect})",
58
- "(when present but with no value, will use \"Text/Normal\" setting of current iTerm tab)" ) do |v|
59
- req[:fill] = v || lambda { |img| img.iterm.session.foreground_color.to_hex }
56
+
57
+ def before_parse_bg req, args
58
+ idx = args.index { |s| %w(-e --exec).include?(s) } or return true
59
+ req[:_exec_this] = args[(idx+1)..-1]
60
+ args.replace idx == 0 ? [] : args[0..(idx-1)]
61
+ true
62
+ end
63
+ protected :before_parse_bg
64
+
65
+ def bg req, *args
66
+ if args.empty?
67
+ if req[:_exec_this]
68
+ args.any? and fail("logic error -- see before_parse_bg.")
69
+ args = req[:_exec_this]
70
+ else
71
+ return get_background
72
+ end
73
+ end
74
+ check_font(req) or return
75
+ img = ImageBuilder.build_background_image(iterm, args, req) or return false
76
+ req[:verbose] and @err.puts "(bg_color: #{img.background_color.inspect})"
77
+ outpath = "#{IMG_DIRNAME}/#{IMG_BASENAME}.#{Process.pid}.png"
78
+ img.write(outpath)
79
+ req[:verbose] and @err.puts "(setting background image to: #{outpath})" # doesn't care if --verbose
80
+ iterm.session.background_image_path = outpath
81
+ if req[:_exec_this]
82
+ @err.puts "(#{program_name} executing: #{req[:_exec_this].join(' ')})"
83
+ exec(req[:_exec_this].join(' '))
84
+ end
85
+ true
60
86
  end
61
- o.on('-v', '--verbose', 'Be verbose.') { req[:verbose] = true }
62
- end
63
87
 
64
- def before_parse_bg req, args
65
- idx = args.index { |s| %w(-e --exec).include?(s) } or return true
66
- req[:_exec_this] = args[(idx+1)..-1]
67
- args.replace idx == 0 ? [] : args[0..(idx-1)]
68
- true
69
- end
70
- protected :before_parse_bg
88
+ DEFAULT_FONT_FILE = "#{ENV['HOME']}/.fonts/MytermDefaultFont.ttf"
89
+ IMG_DIRNAME = '/tmp'
90
+ IMG_BASENAME = 'iTermBG'
71
91
 
72
- def bg req, *args
73
- if args.empty?
74
- if req[:_exec_this]
75
- args.any? and fail("logic error -- see before_parse_bg.")
76
- args = req[:_exec_this]
92
+ private
93
+
94
+ def check_font req
95
+ File.exist?(req[:font_file]) and return true
96
+ if req[:font_file] == DEFAULT_FONT_FILE
97
+ return maybe_download_font req
77
98
  else
78
- return get_background
99
+ font_not_found req
79
100
  end
80
101
  end
81
- check_font(req) or return
82
- img = Myterm::ImageBuilder.build_background_image(iterm, args, req) or return false
83
- req[:verbose] and @err.puts "(bg_color: #{img.background_color.inspect})"
84
- outpath = "#{ImgDirname}/#{ImgBasename}.#{Process.pid}.png"
85
- img.write(outpath)
86
- req[:verbose] and @err.puts "(setting background image to: #{outpath})" # doesn't care if --verbose
87
- iterm.session.background_image_path = outpath
88
- if req[:_exec_this]
89
- @err.puts "(#{program_name} executing: #{req[:_exec_this].join(' ')})"
90
- exec(req[:_exec_this].join(' '))
91
- end
92
- true
93
- end
94
102
 
95
- DefaultFontFile = "#{ENV['HOME']}/.fonts/MytermDefaultFont.ttf"
96
- ImgDirname = '/tmp'
97
- ImgBasename = 'iTermBG'
98
-
99
- private
100
- def check_font req
101
- File.exist?(req[:font_file]) and return true
102
- if req[:font_file] == DefaultFontFile
103
- return maybe_download_font req
104
- else
105
- font_not_found req
103
+ DEFAULT_FONT_URL = 'http://img.dafont.com/dl/?f=simple_life'
104
+ DEFAULT_FONT_FILE_NOT_SIMLINKED = "#{ENV['HOME']}/.fonts/SimpleLife.ttf"
105
+
106
+ def maybe_download_font req
107
+ target = DEFAULT_FONT_FILE_NOT_SIMLINKED
108
+ File.exist?(target) and return true
109
+ $stdin.tty? && $stdout.tty? or return font_not_found(req)
110
+ @err.write "Font file #{pretty_path(req[:font_file])} not found. "
111
+ require 'highline'
112
+ require 'fileutils'
113
+ HighLine.new.agree("Let #{program_name} download it? (Y/n) (recommended: yes)") or return false
114
+ outfile = DEFAULT_FONT_FILE_NOT_SIMLINKED.sub(/\.ttf$/, '.zip')
115
+ font_dir = File.dirname(outfile)
116
+ File.directory?(font_dir) or FileUtils.mkdir_p(font_dir, :verbose => true)
117
+ cmds = ["wget -O #{outfile} #{DEFAULT_FONT_URL}"]
118
+ cmds.push "cd #{font_dir}"
119
+ cmds.push "unzip #{outfile}"
120
+ cmds.push "ln -s #{DEFAULT_FONT_FILE_NOT_SIMLINKED} #{DEFAULT_FONT_FILE}"
121
+ cmds.push("echo 'finished installing for #{program_name}: #{pretty_path(DEFAULT_FONT_FILE_NOT_SIMLINKED)}. " <<
122
+ "Please try using it again.'")
123
+ @err.puts(cmd = cmds.join(' ; '))
124
+ exec(cmd)
106
125
  end
107
- end
108
-
109
- DefaultFontUrl = 'http://img.dafont.com/dl/?f=simple_life'
110
- DefaultFontFileNotSimlinked = "#{ENV['HOME']}/.fonts/SimpleLife.ttf"
111
-
112
- def maybe_download_font req
113
- target = DefaultFontFileNotSimlinked
114
- File.exist?(target) and return true
115
- $stdin.tty? && $stdout.tty? or return font_not_found(req)
116
- @err.write "Font file #{pretty_path(req[:font_file])} not found. "
117
- require 'highline'
118
- require 'fileutils'
119
- HighLine.new.agree("Let #{program_name} download it? (Y/n) (recommended: yes)") or return false
120
- outfile = DefaultFontFileNotSimlinked.sub(/\.ttf$/, '.zip')
121
- font_dir = File.dirname(outfile)
122
- File.directory?(font_dir) or FileUtils.mkdir_p(font_dir, :verbose => true)
123
- cmds = ["wget -O #{outfile} #{DefaultFontUrl}"]
124
- cmds.push "cd #{font_dir}"
125
- cmds.push "unzip #{outfile}"
126
- cmds.push "ln -s #{DefaultFontFileNotSimlinked} #{DefaultFontFile}"
127
- cmds.push("echo 'finished installing for #{program_name}: #{pretty_path(DefaultFontFileNotSimlinked)}. " <<
128
- "Please try using it again.'")
129
- @err.puts(cmd = cmds.join(' ; '))
130
- exec(cmd)
131
- end
132
126
 
133
- def font_not_found req
134
- @err.puts "font file not found: #{pretty_path(req[:font_file])}"
135
- req.command.usage
136
- return false
137
- end
127
+ def font_not_found req
128
+ @err.puts "font file not found: #{pretty_path(req[:font_file])}"
129
+ req.command.usage
130
+ return false
131
+ end
138
132
 
139
- def iterm
140
- @iterm ||= Myterm::ItermProxy.new
141
- end
133
+ def iterm
134
+ @iterm ||= ItermProxy.new
135
+ end
142
136
 
143
- def get_background
144
- @err.puts "tty: #{iterm.session.tty}"
145
- @err.puts "background_image: #{iterm.session.background_image_path.inspect}"
146
- @err.puts "background_color: #{iterm.session.background_color}"
137
+ def get_background
138
+ @err.puts "tty: #{iterm.session.tty}"
139
+ @err.puts "background_image: #{iterm.session.background_image_path.inspect}"
140
+ @err.puts "background_color: #{iterm.session.background_color}"
141
+ end
147
142
  end
148
-
149
143
  end
144
+
@@ -1,16 +1,17 @@
1
1
  require 'optparse'
2
2
 
3
- # an ultralight command-line parser (391 lines)
3
+ # an ultralight command-line parser (407 lines)
4
4
  # that wraps around OptParse (can do anything it does)
5
5
  # with colors
6
6
  # with flexible command-like options ('officious' like -v, -h)
7
7
  # with commands with arguments based off of method signatures
8
8
  # with subcommands, (namespaces) arbitrarily deeply nested
9
9
 
10
- module Tmx; end
11
- module Tmx::Face; end
10
+ module Skylab; end
11
+ module Skylab::Face; end
12
12
 
13
- module Tmx::Face::Colors
13
+ module Skylab::Face::Colors
14
+ extend self
14
15
  def bold str ; style str, :bright, :green end
15
16
  def hi str ; style str, :green end
16
17
  def ohno str ; style str, :red end
@@ -26,7 +27,7 @@ module Tmx::Face::Colors
26
27
  end
27
28
  end
28
29
 
29
- module Tmx::Face
30
+ module Skylab::Face
30
31
  class Command
31
32
 
32
33
  include Colors
@@ -80,12 +81,12 @@ module Tmx::Face
80
81
 
81
82
  def parse argv
82
83
  req = { }
83
- req.send(:instance_variable_set, '@method_parameters', argv)
84
84
  class << req
85
- attr_accessor :method_parameters, :command
85
+ attr_accessor :command
86
+ attr_accessor :method_parameters
86
87
  end
87
- @parent_protected_instance_methods.include?("before_parse_#{@intern}".intern) and
88
- ! @parent.send("before_parse_#{@intern}", req, argv) and return false
88
+ req.method_parameters = argv
89
+ req.command = self
89
90
  begin
90
91
  build_option_parser(req).parse! argv
91
92
  req
@@ -96,10 +97,11 @@ module Tmx::Face
96
97
  end
97
98
  end
98
99
 
100
+ NoUsageRe = /\A#{Regexp.escape(Skylab::Face::Colors.hi('usage:'))} /
101
+
99
102
  def summary
100
- build_option_parser({}).to_s.
101
- sub(/\A#{Regexp.escape(hi('usage:'))} /, '').
102
- split("\n").select{ |s| ! s.strip.empty? }
103
+ build_option_parser({}).to_s =~ /\A[\n]*([^\n]*)(\n+[^\n])?/
104
+ [ "#{$1}#{ ' [..]' if $2 }".sub(NoUsageRe, '') ]
103
105
  end
104
106
 
105
107
  def syntax *args
@@ -125,10 +127,8 @@ module Tmx::Face
125
127
  def invocation_string
126
128
  "#{@parent.invocation_string} #{name}"
127
129
  end
128
- alias_method :path, :invocation_string
129
130
  def parent= parent
130
131
  @parent and fail("won't overwrite existing parent")
131
- @parent_protected_instance_methods = parent.class.protected_instance_methods(false).map(&:intern)
132
132
  @parent = parent
133
133
  end
134
134
  def usage msg=nil
@@ -159,7 +159,8 @@ module Tmx::Face
159
159
  # option_definitions.reject! { |a,_| '-h' == a.first }
160
160
  end
161
161
  def namespace name, &block
162
- command_definitions.push [Namespace, [name], block]
162
+ def_block = name.kind_of?(Array) ? name : [Namespace, [name], block]
163
+ command_definitions.push Namespace.add_definition(def_block)
163
164
  end
164
165
  def on *a, &b
165
166
  block_given? or raise ArgumentError.new("block required")
@@ -277,6 +278,19 @@ module Tmx::Face
277
278
  class Namespace
278
279
  extend TreeDefiner, Colors
279
280
  include Treeish, Nodeish, Colors
281
+ @definitions ||= []
282
+ class << self
283
+ def add_definition arr
284
+ @definitions.push arr
285
+ arr
286
+ end
287
+ def namespaces
288
+ @definitions.each_with_index do |defn, idx|
289
+ defn.kind_of?(Class) or @definitions[idx] = defn[0].build(*defn[1], &defn[2])
290
+ end
291
+ @definitions
292
+ end
293
+ end
280
294
  alias_method :interface, :class
281
295
  def init_for_run parent, name_as_used
282
296
  @name_as_used = name_as_used
@@ -290,6 +304,7 @@ module Tmx::Face
290
304
  end
291
305
  alias_method :inspect, :name
292
306
  def self.build name, &block
307
+ name.kind_of?(Symbol) or return name
293
308
  name = name.to_s
294
309
  Class.new(self).class_eval do
295
310
  self.namespace_name = name
@@ -330,11 +345,12 @@ module Tmx::Face
330
345
  end
331
346
  end
332
347
 
333
- class Tmx::Face::Cli
334
- extend Tmx::Face::Command::TreeDefiner
335
- include Tmx::Face::Colors
336
- include Tmx::Face::Command::Nodeish
337
- include Tmx::Face::Command::Treeish
348
+ class Skylab::Face::Cli
349
+ Face = Skylab::Face
350
+ extend Face::Command::TreeDefiner
351
+ include Face::Colors
352
+ include Face::Command::Nodeish
353
+ include Face::Command::Treeish
338
354
 
339
355
  def initialize
340
356
  @out = $stdout
@@ -362,7 +378,6 @@ class Tmx::Face::Cli
362
378
  end while (cmd and cmd.respond_to?(:find_command) and runner = cmd)
363
379
  cmd and req = cmd.parse(argv) and
364
380
  begin
365
- req.command = cmd
366
381
  runner.send(cmd.method_symbol, req, * req.method_parameters)
367
382
  rescue ArgumentError => e
368
383
  argument_error e, cmd
data/myterm.gemspec CHANGED
@@ -1,10 +1,10 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
- require "myterm/version"
3
+ require 'myterm/api'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "myterm"
7
- s.version = Skylab::Myterm::VERSION
7
+ s.version = Skylab::Myterm.version
8
8
  s.authors = ["Mark Meves"]
9
9
  s.email = ["mark.meves@gmail.com"]
10
10
  s.homepage = "http://botnoise.org"
@@ -14,8 +14,11 @@ Gem::Specification.new do |s|
14
14
 
15
15
  s.rubyforge_project = "myterm"
16
16
 
17
- s.add_dependency 'rb-appscript'
18
17
  s.add_dependency 'highline'
18
+ s.add_dependency 'rb-appscript'
19
+ s.add_dependency 'rmagick' # i had 2.13.1
20
+
21
+ s.add_development_dependency 'rake'
19
22
  s.add_development_dependency "ruby-debug19"
20
23
 
21
24
  s.files = `git ls-files`.split("\n")
@@ -23,3 +26,4 @@ Gem::Specification.new do |s|
23
26
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
27
  s.require_paths = ["lib"]
25
28
  end
29
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: myterm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,23 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-06 00:00:00.000000000 -04:00
12
+ date: 2012-01-24 00:00:00.000000000 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: highline
17
+ requirement: &70123357981900 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70123357981900
15
26
  - !ruby/object:Gem::Dependency
16
27
  name: rb-appscript
17
- requirement: &70161455195900 !ruby/object:Gem::Requirement
28
+ requirement: &70123357981460 !ruby/object:Gem::Requirement
18
29
  none: false
19
30
  requirements:
20
31
  - - ! '>='
@@ -22,10 +33,10 @@ dependencies:
22
33
  version: '0'
23
34
  type: :runtime
24
35
  prerelease: false
25
- version_requirements: *70161455195900
36
+ version_requirements: *70123357981460
26
37
  - !ruby/object:Gem::Dependency
27
- name: highline
28
- requirement: &70161455195480 !ruby/object:Gem::Requirement
38
+ name: rmagick
39
+ requirement: &70123357981040 !ruby/object:Gem::Requirement
29
40
  none: false
30
41
  requirements:
31
42
  - - ! '>='
@@ -33,10 +44,21 @@ dependencies:
33
44
  version: '0'
34
45
  type: :runtime
35
46
  prerelease: false
36
- version_requirements: *70161455195480
47
+ version_requirements: *70123357981040
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ requirement: &70123357980620 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *70123357980620
37
59
  - !ruby/object:Gem::Dependency
38
60
  name: ruby-debug19
39
- requirement: &70161455195060 !ruby/object:Gem::Requirement
61
+ requirement: &70123357980200 !ruby/object:Gem::Requirement
40
62
  none: false
41
63
  requirements:
42
64
  - - ! '>='
@@ -44,7 +66,7 @@ dependencies:
44
66
  version: '0'
45
67
  type: :development
46
68
  prerelease: false
47
- version_requirements: *70161455195060
69
+ version_requirements: *70123357980200
48
70
  description: Command line interface for customizing iTerm using AppleScript. Creates
49
71
  meaningful, salient, eye-catching background images that help to discern between
50
72
  iTerm windows.
@@ -59,16 +81,17 @@ files:
59
81
  - .gitignore
60
82
  - .repath.sh
61
83
  - .rvmrc.example
84
+ - CHANGELOG.md
62
85
  - Gemfile
63
86
  - Gemfile.lock
64
87
  - README.md
88
+ - VERSION
65
89
  - bin/myterm
66
90
  - doc/HISTORY.md
67
91
  - lib-iterm.sh
68
92
  - lib/myterm/api.rb
69
93
  - lib/myterm/cli.rb
70
- - lib/myterm/vendor/face/cli.rb
71
- - lib/myterm/version.rb
94
+ - lib/myterm/vendor/skylab/face/cli.rb
72
95
  - myterm.gemspec
73
96
  has_rdoc: true
74
97
  homepage: http://botnoise.org
@@ -1,4 +0,0 @@
1
- module Skylab; end
2
- module Skylab::Myterm
3
- VERSION = "0.0.3"
4
- end