myterm 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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