termtter 1.5.0 → 1.6.0
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/Rakefile +2 -1
- data/bin/termtter +1 -0
- data/lib/plugins/another_prompt.rb +131 -0
- data/lib/plugins/async.rb +23 -0
- data/lib/plugins/confirm.rb +1 -1
- data/lib/plugins/db.rb +1 -1
- data/lib/plugins/defaults/auto_reload.rb +20 -19
- data/lib/plugins/defaults/command_line.rb +10 -5
- data/lib/plugins/defaults/hashtag.rb +35 -0
- data/lib/plugins/defaults/lists.rb +14 -0
- data/lib/plugins/defaults/retweet.rb +15 -15
- data/lib/plugins/defaults/standard_commands.rb +22 -28
- data/lib/plugins/defaults/standard_completion.rb +5 -5
- data/lib/plugins/defaults/switch.rb +34 -0
- data/lib/plugins/eject.rb +15 -0
- data/lib/plugins/expand-tinyurl.rb +1 -1
- data/lib/plugins/favotter.rb +77 -0
- data/lib/plugins/friends.rb +50 -0
- data/lib/plugins/g.rb +16 -0
- data/lib/plugins/gsub.rb +17 -0
- data/lib/plugins/haml.rb +55 -0
- data/lib/plugins/hatebu_and_update.rb +2 -2
- data/lib/plugins/history.rb +9 -0
- data/lib/plugins/irc_gw.rb +11 -4
- data/lib/plugins/linefeed.rb +31 -0
- data/lib/plugins/md5pass.rb +42 -0
- data/lib/plugins/outputz.rb +1 -1
- data/lib/plugins/primes.rb +1 -1
- data/lib/plugins/quote.rb +43 -0
- data/lib/plugins/reduce_text.rb +26 -0
- data/lib/plugins/reverse.rb +7 -6
- data/lib/plugins/source.rb +31 -0
- data/lib/plugins/storage/status.rb +2 -2
- data/lib/plugins/storage.rb +1 -1
- data/lib/plugins/stream.rb +192 -0
- data/lib/plugins/switch_user.rb +1 -22
- data/lib/plugins/truncate.rb +29 -0
- data/lib/plugins/uri-open.rb +23 -9
- data/lib/plugins/w3mimg.rb +76 -0
- data/lib/termtter/active_rubytter.rb +8 -0
- data/lib/termtter/api.rb +37 -13
- data/lib/termtter/client.rb +26 -47
- data/lib/termtter/command.rb +15 -9
- data/lib/termtter/config.rb +6 -2
- data/lib/termtter/hookable.rb +59 -0
- data/lib/termtter/optparse.rb +51 -39
- data/lib/termtter/rubytter_proxy.rb +32 -0
- data/lib/termtter/system_extensions/core_compatibles.rb +16 -0
- data/lib/termtter/system_extensions/termtter_compatibles.rb +19 -0
- data/lib/termtter/system_extensions/windows.rb +86 -0
- data/lib/termtter/system_extensions.rb +8 -121
- data/lib/termtter/task_manager.rb +4 -10
- data/lib/termtter/version.rb +1 -1
- data/lib/termtter.rb +5 -3
- data/spec/plugins/defaults/hashtag_spec.rb +41 -0
- data/spec/plugins/defaults/lists_spec.rb +34 -0
- data/spec/plugins/{english_spec.rb → english_spec_.rb} +0 -0
- data/spec/plugins/{filter_spec.rb → filter_spec_.rb} +0 -0
- data/spec/plugins/gsub_spec.rb +18 -0
- data/spec/plugins/haml_spec.rb +134 -0
- data/spec/plugins/md5pass_spec.rb +13 -0
- data/spec/plugins/{primes_spec.rb → primes_spec_.rb} +0 -0
- data/spec/plugins/{sl_spec.rb → sl_spec_.rb} +0 -0
- data/spec/plugins/standard_commands_spec.rb +1 -1
- data/spec/plugins/storage/{DB_spec.rb → DB_spec_.rb} +0 -0
- data/spec/plugins/storage/{status_spec.rb → status_spec_.rb} +0 -0
- data/spec/plugins/truncate_spec.rb +27 -0
- data/spec/plugins/whois_spec_.rb +20 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/termtter/active_rubytter_spec.rb +17 -0
- data/spec/termtter/api_spec.rb +107 -0
- data/spec/termtter/client_spec.rb +262 -73
- data/spec/termtter/command_spec.rb +31 -5
- data/spec/termtter/config_setup_spec.rb +19 -0
- data/spec/termtter/config_spec.rb +57 -27
- data/spec/termtter/hook_spec.rb +12 -0
- data/spec/termtter/hookable_spec.rb +53 -0
- data/spec/termtter/optparse_spec.rb +64 -9
- data/spec/termtter/rubytter_proxy_spec.rb +42 -0
- data/spec/termtter/system_extensions/windows_spec.rb +9 -0
- data/spec/termtter/system_extensions_spec.rb +61 -0
- data/spec/termtter/task_manager_spec.rb +58 -0
- data/spec/termtter_spec.rb +11 -0
- metadata +45 -20
- data/lib/termtter/connection.rb +0 -41
- data/spec/plugins/whois_spec.rb +0 -26
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
def multibyte_string(text)
|
4
|
+
text.unpack('U*')
|
5
|
+
end
|
6
|
+
|
7
|
+
def truncate(text, length = 140, omission = "...")
|
8
|
+
o = multibyte_string(omission)
|
9
|
+
l = length - o.length
|
10
|
+
chars = multibyte_string(text)
|
11
|
+
chars.length > length ? (chars[0...l] + o).pack('U*') : text
|
12
|
+
end
|
13
|
+
|
14
|
+
Termtter::RubytterProxy.register_hook(
|
15
|
+
:name => :truncate_status,
|
16
|
+
:points => [:pre_update],
|
17
|
+
:exec_proc => lambda do |*args|
|
18
|
+
return unless args
|
19
|
+
return args if args.length < 1
|
20
|
+
status = args[0]
|
21
|
+
return args if multibyte_string(status).length <= 140
|
22
|
+
if Termtter::Client::confirm("You are status contents more than 140 characters. do end endyou want abbreviation status?", true)
|
23
|
+
args[0] = truncate(status)
|
24
|
+
else
|
25
|
+
puts 'canceled.'
|
26
|
+
raise Termtter::HookCanceled
|
27
|
+
end
|
28
|
+
end
|
29
|
+
)
|
data/lib/plugins/uri-open.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
+
require 'uri'
|
4
|
+
|
3
5
|
module Termtter::Client
|
4
6
|
public_storage[:uris] = []
|
5
7
|
|
8
|
+
PROTOCOLS = %w(http https)
|
9
|
+
|
6
10
|
register_hook(
|
7
11
|
:name => :uri_open,
|
8
12
|
:points => [:output],
|
9
13
|
:exec_proc => lambda {|statuses, event|
|
10
14
|
statuses.each do |s|
|
11
|
-
public_storage[:uris]
|
15
|
+
public_storage[:uris].unshift *URI.extract(s[:text], PROTOCOLS)
|
12
16
|
end
|
13
17
|
}
|
14
18
|
)
|
@@ -21,23 +25,24 @@ module Termtter::Client
|
|
21
25
|
case RUBY_PLATFORM
|
22
26
|
when /linux/; 'firefox'
|
23
27
|
when /mswin(?!ce)|mingw|bccwin/; 'explorer'
|
28
|
+
when /cygwin/; 'cygstart -o'
|
24
29
|
else; 'open'
|
25
30
|
end
|
26
31
|
end
|
27
|
-
system cmd
|
32
|
+
system "#{cmd} #{uri}"
|
28
33
|
end
|
29
34
|
|
30
35
|
register_command(
|
31
36
|
:name => :'uri-open', :aliases => [:uo],
|
32
37
|
:exec_proc => lambda {|arg|
|
33
|
-
case arg
|
38
|
+
case arg.strip
|
34
39
|
when ''
|
35
40
|
open_uri public_storage[:uris].shift
|
36
|
-
when
|
41
|
+
when /^all$/
|
37
42
|
public_storage[:uris].
|
38
43
|
each {|uri| open_uri(uri) }.
|
39
44
|
clear
|
40
|
-
when
|
45
|
+
when /^list$/
|
41
46
|
public_storage[:uris].
|
42
47
|
enum_for(:each_with_index).
|
43
48
|
to_a.
|
@@ -45,20 +50,29 @@ module Termtter::Client
|
|
45
50
|
each do |uri, index|
|
46
51
|
puts "#{index}: #{uri}"
|
47
52
|
end
|
48
|
-
when
|
53
|
+
when /^delete\s+(\d+)$/
|
49
54
|
puts 'delete'
|
50
55
|
public_storage[:uris].delete_at($1.to_i)
|
51
|
-
when
|
56
|
+
when /^clear$/
|
52
57
|
public_storage[:uris].clear
|
53
58
|
puts "clear uris"
|
54
|
-
when
|
59
|
+
when /^in\s+(.*)$/
|
60
|
+
$1.split(/\s+/).each do |id|
|
61
|
+
if s = Termtter::API.twitter.show(id) rescue nil
|
62
|
+
URI.extract(s.text, PROTOCOLS).each do |uri|
|
63
|
+
open_uri(uri)
|
64
|
+
public_storage[:uris].delete(uri)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
when /^(\d+)$/
|
55
69
|
open_uri(public_storage[:uris].delete_at($1.to_i))
|
56
70
|
else
|
57
71
|
puts "**parse error in uri-open**"
|
58
72
|
end
|
59
73
|
},
|
60
74
|
:completion_proc => lambda {|cmd, arg|
|
61
|
-
%w(all list delete clear).grep(/^#{Regexp.quote arg}/).map {|a| "#{cmd} #{a}" }
|
75
|
+
%w(all list delete clear in).grep(/^#{Regexp.quote arg}/).map {|a| "#{cmd} #{a}" }
|
62
76
|
}
|
63
77
|
)
|
64
78
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'fileutils'
|
3
|
+
require 'RMagick' # apt-get install librmagick-ruby
|
4
|
+
require 'uri'
|
5
|
+
require 'open3'
|
6
|
+
require 'terminfo'
|
7
|
+
|
8
|
+
# TODO should be DRY: Copy from notify-send3.rb
|
9
|
+
config.plugins.notify_send.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
|
10
|
+
def get_icon_path(s)
|
11
|
+
FileUtils.mkdir_p(config.plugins.notify_send.icon_cache_dir) unless File.exist?(config.plugins.notify_send.icon_cache_dir)
|
12
|
+
cache_file = "%s/%s%s" % [ config.plugins.notify_send.icon_cache_dir,
|
13
|
+
s.user.screen_name,
|
14
|
+
File.extname(s.user.profile_image_url) ]
|
15
|
+
if !File.exist?(cache_file) || (File.atime(cache_file) + 24*60*60) < Time.now
|
16
|
+
File.open(cache_file, "wb") do |f|
|
17
|
+
begin
|
18
|
+
http_class = Net::HTTP
|
19
|
+
unless config.proxy.host.nil? or config.proxy.host.empty?
|
20
|
+
http_class = Net::HTTP::Proxy(config.proxy.host,
|
21
|
+
config.proxy.port,
|
22
|
+
config.proxy.user_name,
|
23
|
+
config.proxy.password)
|
24
|
+
end
|
25
|
+
uri = URI.parse(URI.escape(s.user.profile_image_url))
|
26
|
+
image = http_class.get(uri.host, uri.path, uri.port)
|
27
|
+
rimage = Magick::Image.from_blob(image).first
|
28
|
+
rimage = rimage.resize_to_fill(48, 48)
|
29
|
+
f << rimage.to_blob
|
30
|
+
rescue Net::ProtocolError
|
31
|
+
return nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
cache_file
|
36
|
+
end
|
37
|
+
|
38
|
+
module Termtter::Client
|
39
|
+
|
40
|
+
W3MIMG = '/usr/lib/w3m/w3mimgdisplay'
|
41
|
+
W3MIMGSTDIN, stdout, stderr = *Open3.popen3(W3MIMG)
|
42
|
+
|
43
|
+
sizestr = `#{W3MIMG} -test`.chomp
|
44
|
+
PW, PH = sizestr.split.map(&:to_i)
|
45
|
+
CH, CW = TermInfo.screen_size()
|
46
|
+
LINEH = PH / CH
|
47
|
+
@w3mimgicons = []
|
48
|
+
|
49
|
+
register_hook(
|
50
|
+
:name => :w3mimg,
|
51
|
+
:points => [:output],
|
52
|
+
:exec_proc => lambda {|statuses, event|
|
53
|
+
return unless event == :update_friends_timeline
|
54
|
+
Thread.start do
|
55
|
+
newicons = statuses.reverse.map do |s|
|
56
|
+
lines = s.text.count("\n") + 1
|
57
|
+
file = get_icon_path(s)
|
58
|
+
[file, lines]
|
59
|
+
end
|
60
|
+
@w3mimgicons = (newicons + @w3mimgicons).take(CH)
|
61
|
+
sleep 0.5
|
62
|
+
w, h = 48, 48
|
63
|
+
x = PW - w
|
64
|
+
y = PH - LINEH
|
65
|
+
@w3mimgicons.each do |i|
|
66
|
+
file, lines = i
|
67
|
+
sh = LINEH * lines
|
68
|
+
y -= sh
|
69
|
+
W3MIMGSTDIN.print "2;3;\n0;1;#{x};#{y};#{w};#{h};0;0;0;#{sh};#{file}\n4\n3;\n"
|
70
|
+
break if y <= 0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
}
|
74
|
+
)
|
75
|
+
|
76
|
+
end
|
data/lib/termtter/api.rb
CHANGED
@@ -13,23 +13,47 @@ module Termtter
|
|
13
13
|
class << self
|
14
14
|
attr_reader :connection, :twitter
|
15
15
|
def setup
|
16
|
-
@connection = Connection.new
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
3.times do
|
18
|
+
begin
|
19
|
+
if twitter = try_auth
|
20
|
+
@twitter = twitter
|
21
|
+
# NOTE: for compatible
|
22
|
+
@connection = twitter.instance_variable_get(:@connection)
|
23
|
+
break
|
24
|
+
end
|
25
|
+
rescue Timeout::Error
|
26
|
+
puts TermColor.parse("<red>Time out :(</red>")
|
27
|
+
exit!
|
28
|
+
end
|
29
|
+
end
|
23
30
|
|
24
|
-
|
25
|
-
@twitter = create_twitter(config.user_name, config.password)
|
31
|
+
exit! unless twitter
|
26
32
|
end
|
27
33
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
34
|
+
def try_auth
|
35
|
+
if config.user_name.empty? || config.password.empty?
|
36
|
+
puts 'Please enter your Twitter login:'
|
37
|
+
end
|
38
|
+
|
39
|
+
ui = create_highline
|
40
|
+
|
41
|
+
if config.user_name.empty?
|
42
|
+
config.user_name = ui.ask('Username: ')
|
43
|
+
end
|
44
|
+
if config.password.empty?
|
45
|
+
config.password = ui.ask('Password: ') { |q| q.echo = false}
|
46
|
+
end
|
47
|
+
|
48
|
+
twitter = RubytterProxy.new(config.user_name, config.password, twitter_option)
|
49
|
+
begin
|
50
|
+
twitter.verify_credentials
|
51
|
+
return twitter
|
52
|
+
rescue Rubytter::APIError
|
53
|
+
config.__clear__(:user_name)
|
54
|
+
config.__clear__(:password)
|
55
|
+
end
|
56
|
+
return nil
|
33
57
|
end
|
34
58
|
|
35
59
|
def twitter_option
|
data/lib/termtter/client.rb
CHANGED
@@ -9,22 +9,23 @@ module Termtter
|
|
9
9
|
|
10
10
|
module Client
|
11
11
|
|
12
|
-
|
12
|
+
include Termtter::Hookable
|
13
|
+
|
13
14
|
@commands = {}
|
14
15
|
@filters = []
|
15
16
|
@since_id = nil
|
16
|
-
@task_manager = Termtter::TaskManager.new
|
17
17
|
|
18
18
|
config.set_default(:logger, nil)
|
19
19
|
config.set_default(:update_interval, 120)
|
20
20
|
config.set_default(:prompt, '> ')
|
21
21
|
config.set_default(:devel, false)
|
22
|
+
config.set_default(:timeout, 5)
|
22
23
|
|
23
24
|
Thread.abort_on_exception = true
|
24
25
|
|
25
26
|
class << self
|
26
27
|
|
27
|
-
attr_reader :commands
|
28
|
+
attr_reader :commands
|
28
29
|
|
29
30
|
# plug :: Name -> (Hash) -> IO () where NAME = String | Symbol | [NAME]
|
30
31
|
def plug(name, options = {})
|
@@ -53,34 +54,6 @@ module Termtter
|
|
53
54
|
@filters.clear
|
54
55
|
end
|
55
56
|
|
56
|
-
def register_hook(arg, opts = {}, &block)
|
57
|
-
hook = case arg
|
58
|
-
when Hook
|
59
|
-
arg
|
60
|
-
when Hash
|
61
|
-
Hook.new(arg)
|
62
|
-
when String, Symbol
|
63
|
-
options = { :name => arg }
|
64
|
-
options.merge!(opts)
|
65
|
-
options[:exec_proc] = block
|
66
|
-
Hook.new(options)
|
67
|
-
else
|
68
|
-
raise ArgumentError, 'must be given Termtter::Hook, Hash, String or Symbol'
|
69
|
-
end
|
70
|
-
@hooks[hook.name] = hook
|
71
|
-
end
|
72
|
-
|
73
|
-
def get_hook(name)
|
74
|
-
@hooks[name]
|
75
|
-
end
|
76
|
-
|
77
|
-
def get_hooks(point)
|
78
|
-
# TODO: sort by alphabet
|
79
|
-
@hooks.values.select do |hook|
|
80
|
-
hook.match?(point)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
57
|
def register_command(arg, opts = {}, &block)
|
85
58
|
command = case arg
|
86
59
|
when Command
|
@@ -112,6 +85,7 @@ module Termtter
|
|
112
85
|
@commands.clear
|
113
86
|
end
|
114
87
|
|
88
|
+
# MEMO: attr_reader :commands してるからこれいらない気もする
|
115
89
|
def get_command(name)
|
116
90
|
@commands[name]
|
117
91
|
end
|
@@ -151,7 +125,7 @@ module Termtter
|
|
151
125
|
call_hooks(:post_filter, filtered, event)
|
152
126
|
get_hooks(:output).each do |hook|
|
153
127
|
hook.call(
|
154
|
-
apply_filters_for_hook("filter_for_#{hook.name}", filtered, event),
|
128
|
+
apply_filters_for_hook(:"filter_for_#{hook.name}", filtered, event),
|
155
129
|
event
|
156
130
|
)
|
157
131
|
end
|
@@ -163,17 +137,12 @@ module Termtter
|
|
163
137
|
}
|
164
138
|
end
|
165
139
|
|
166
|
-
# return last hook return value
|
167
|
-
def call_hooks(point, *args)
|
168
|
-
result = nil
|
169
|
-
get_hooks(point).each {|hook|
|
170
|
-
break if result == false # interrupt if hook return false
|
171
|
-
result = hook.call(*args)
|
172
|
-
}
|
173
|
-
result
|
174
|
-
end
|
175
|
-
|
176
140
|
def call_commands(text)
|
141
|
+
# status
|
142
|
+
# 0: done
|
143
|
+
# 1: canceled
|
144
|
+
status = 0
|
145
|
+
|
177
146
|
@task_manager.invoke_and_wait do
|
178
147
|
# FIXME: This block can become Maybe Monad
|
179
148
|
get_hooks("pre_command").each {|hook|
|
@@ -186,7 +155,7 @@ module Termtter
|
|
186
155
|
raise CommandNotFound, text if commands.empty?
|
187
156
|
|
188
157
|
commands.each do |command|
|
189
|
-
command_str, command_arg =
|
158
|
+
command_str, command_arg = command.split_command_line(text)
|
190
159
|
|
191
160
|
modified_arg = command_arg
|
192
161
|
# FIXME: This block can become Maybe Monad
|
@@ -200,10 +169,15 @@ module Termtter
|
|
200
169
|
result = command.call(command_str, modified_arg, text) # exec command
|
201
170
|
call_hooks("post_exec_#{command.name.to_s}", command_str, modified_arg, result)
|
202
171
|
rescue CommandCanceled
|
172
|
+
status = 1
|
203
173
|
end
|
204
174
|
end
|
205
175
|
call_hooks("post_command", text)
|
176
|
+
status
|
206
177
|
end
|
178
|
+
rescue TimeoutError
|
179
|
+
call_hooks("timeout", text)
|
180
|
+
raise
|
207
181
|
end
|
208
182
|
|
209
183
|
def command_exists?(text)
|
@@ -304,12 +278,17 @@ module Termtter
|
|
304
278
|
@init_block.call(self) if @init_block
|
305
279
|
end
|
306
280
|
|
281
|
+
def setup_task_manager
|
282
|
+
@task_manager = Termtter::TaskManager.new(1)
|
283
|
+
end
|
284
|
+
|
307
285
|
def run
|
308
286
|
load_config()
|
309
|
-
Termtter::API.setup()
|
310
287
|
setup_logger()
|
288
|
+
setup_task_manager()
|
311
289
|
load_plugins()
|
312
290
|
eval_init_block()
|
291
|
+
Termtter::API.setup()
|
313
292
|
|
314
293
|
config.system.eval_scripts.each do |script|
|
315
294
|
begin
|
@@ -331,14 +310,14 @@ module Termtter
|
|
331
310
|
def handle_error(e)
|
332
311
|
if logger
|
333
312
|
logger.error("#{e.class.to_s}: #{e.message}")
|
334
|
-
logger.error(e.backtrace.join("\n")) if config.devel
|
313
|
+
logger.error(e.backtrace.join("\n")) if (e.backtrace and config.devel)
|
335
314
|
else
|
336
315
|
raise e
|
337
316
|
end
|
338
317
|
get_hooks(:on_error).each {|hook| hook.call(e) }
|
339
318
|
rescue Exception => e
|
340
|
-
puts "Error: #{e}"
|
341
|
-
puts e.backtrace.join("\n")
|
319
|
+
$stderr.puts "Error: #{e}"
|
320
|
+
$stderr.puts e.backtrace.join("\n")
|
342
321
|
end
|
343
322
|
|
344
323
|
def confirm(message, default_yes = true, &block)
|
data/lib/termtter/command.rb
CHANGED
@@ -28,18 +28,18 @@ module Termtter
|
|
28
28
|
|
29
29
|
# set :: Hash -> ()
|
30
30
|
def set(cfg)
|
31
|
-
self.name
|
32
|
-
self.aliases
|
33
|
-
self.exec_proc
|
34
|
-
self.completion_proc
|
35
|
-
self.help
|
31
|
+
self.name = cfg[:name].to_sym
|
32
|
+
self.aliases = cfg[:aliases]
|
33
|
+
self.exec_proc = cfg[:exec_proc]
|
34
|
+
self.completion_proc = cfg[:completion_proc]
|
35
|
+
self.help = cfg[:help]
|
36
36
|
end
|
37
37
|
|
38
38
|
# complement :: String -> [String]
|
39
39
|
def complement(input)
|
40
40
|
if match?(input) && input =~ /^[^\s]+\s/
|
41
41
|
if completion_proc
|
42
|
-
command_str, command_arg =
|
42
|
+
command_str, command_arg = split_command_line(input)
|
43
43
|
[completion_proc.call(command_str, command_arg || '')].flatten.compact
|
44
44
|
else
|
45
45
|
[]
|
@@ -64,7 +64,7 @@ module Termtter
|
|
64
64
|
|
65
65
|
# match? :: String -> Boolean
|
66
66
|
def match?(input)
|
67
|
-
|
67
|
+
pattern === input
|
68
68
|
end
|
69
69
|
|
70
70
|
# pattern :: Regexp
|
@@ -87,9 +87,15 @@ module Termtter
|
|
87
87
|
self.aliases = [a]
|
88
88
|
end
|
89
89
|
|
90
|
+
def command_words
|
91
|
+
name.to_s.split(/\s+/)
|
92
|
+
end
|
93
|
+
|
90
94
|
# split_command_line :: String -> (String, String)
|
91
|
-
def
|
92
|
-
|
95
|
+
def split_command_line(line)
|
96
|
+
command_words_count = command_words.size
|
97
|
+
parts = line.strip.split(/\s+/, command_words_count + 1)
|
98
|
+
[parts[0...command_words_count].join(' '), parts[command_words_count]]
|
93
99
|
end
|
94
100
|
end
|
95
101
|
end
|
data/lib/termtter/config.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Termtter
|
4
|
+
class HookCanceled < StandardError; end
|
5
|
+
|
6
|
+
module Hookable
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
@hooks = {}
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_reader :hooks
|
13
|
+
|
14
|
+
def register_hook(arg, opts = {}, &block)
|
15
|
+
hook = case arg
|
16
|
+
when Hook
|
17
|
+
arg
|
18
|
+
when Hash
|
19
|
+
Hook.new(arg)
|
20
|
+
when String, Symbol
|
21
|
+
options = { :name => arg }
|
22
|
+
options.merge!(opts)
|
23
|
+
options[:exec_proc] = block
|
24
|
+
Hook.new(options)
|
25
|
+
else
|
26
|
+
raise ArgumentError, 'must be given Termtter::Hook, Hash, String or Symbol'
|
27
|
+
end
|
28
|
+
hooks[hook.name] = hook
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_hook(name)
|
32
|
+
hooks[name]
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_hooks(point)
|
36
|
+
# TODO: sort by alphabet
|
37
|
+
hooks.values.select do |hook|
|
38
|
+
hook.match?(point)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# return last hook return value
|
43
|
+
def call_hooks(point, *args)
|
44
|
+
result = nil
|
45
|
+
get_hooks(point).each {|hook|
|
46
|
+
break if result == false # interrupt if hook return false
|
47
|
+
result = hook.call(*args)
|
48
|
+
}
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
def clear_hooks
|
53
|
+
hooks.clear
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/termtter/optparse.rb
CHANGED
@@ -1,51 +1,63 @@
|
|
1
|
-
OptionParser.new { |opt|
|
2
|
-
opt.program_name = 'Termtter'
|
3
1
|
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Termtter
|
3
|
+
module OptParser
|
4
|
+
class << self
|
5
|
+
def parse!(argv)
|
6
|
+
@optionparser.parse!(argv)
|
7
|
+
end
|
8
|
+
end
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
end
|
10
|
+
@optionparser = OptionParser.new { |opt|
|
11
|
+
opt.program_name = 'Termtter'
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
opt.on('-f', '--config-file file', 'Set path to configfile') do |val|
|
14
|
+
config.system.__assign__(:conf_file, val)
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
17
|
+
opt.on('-t', '--termtter-directory directory', 'Set termtter directory') do |val|
|
18
|
+
config.system.__assign__(:conf_dir, val)
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
21
|
+
opt.on('-d', '--devel', 'Start in developer mode') do |flg|
|
22
|
+
config.__assign__(:devel, true) if flg
|
23
|
+
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
config.system.cmd_mode = false
|
26
|
+
opt.on('-c', '--command-mode', 'Run as command mode') do |flg|
|
27
|
+
config.system.cmd_mode = flg
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
config.system.run_commands = []
|
31
|
+
opt.on('-r', '--run-command command', 'Run command') do |cmd|
|
32
|
+
config.system.run_commands << cmd
|
33
|
+
end
|
34
|
+
|
35
|
+
config.system.load_plugins = []
|
36
|
+
opt.on('-p', '--plugin plugin', 'Load plugin') do |plugin|
|
37
|
+
config.system.load_plugins << plugin
|
38
|
+
end
|
35
39
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
config.system.eval_scripts = []
|
41
|
+
opt.on('-e', '--eval-script script', 'Eval script') do |script|
|
42
|
+
config.system.eval_scripts << script
|
43
|
+
end
|
44
|
+
|
45
|
+
config.system.eval_scripts = []
|
46
|
+
opt.on('-m', '--monochrome', 'No shell escapes for color highlightings') do |script|
|
47
|
+
require 'termcolor'
|
48
|
+
module ::TermColor
|
49
|
+
class << self
|
50
|
+
alias parse_orig parse
|
51
|
+
def parse(o)
|
52
|
+
o.gsub(/<.+?>(.*?)<\/.+?>/, '\1')
|
53
|
+
end
|
54
|
+
end
|
44
55
|
end
|
45
56
|
end
|
46
|
-
|
57
|
+
|
58
|
+
opt.version = Termtter::VERSION
|
59
|
+
}
|
60
|
+
|
47
61
|
end
|
62
|
+
end
|
48
63
|
|
49
|
-
opt.version = Termtter::VERSION
|
50
|
-
opt.parse!(ARGV)
|
51
|
-
}
|