termtter 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/README.rdoc +2 -2
- data/Rakefile +41 -75
- data/VERSION +1 -0
- data/bin/termtter +9 -2
- data/doc/Termtter-1.0-Release-Note-English.txt +37 -0
- data/doc/Termtter-1.0-Release-Note.txt +37 -0
- data/lib/plugins/another_prompt.rb +8 -8
- data/lib/plugins/ar.rb +102 -0
- data/lib/plugins/async.rb +1 -1
- data/lib/plugins/babelfish.rb +34 -0
- data/lib/plugins/confirm.rb +2 -0
- data/lib/plugins/crypt.rb +44 -0
- data/lib/plugins/defaults/auto_reload.rb +1 -1
- data/lib/plugins/defaults/command_line.rb +34 -17
- data/lib/plugins/defaults/confirm.rb +30 -0
- data/lib/plugins/defaults/hashtag.rb +1 -1
- data/lib/plugins/defaults/irb.rb +30 -0
- data/lib/plugins/defaults/keyword.rb +58 -0
- data/lib/plugins/defaults/list.rb +155 -0
- data/lib/plugins/defaults/plugin.rb +59 -0
- data/lib/plugins/defaults/retweet.rb +75 -23
- data/lib/plugins/defaults/standard_commands.rb +60 -87
- data/lib/plugins/defaults/standard_completion.rb +25 -15
- data/lib/plugins/defaults/stdout.rb +49 -10
- data/lib/plugins/defaults/switch.rb +1 -1
- data/lib/plugins/defaults/users.rb +63 -0
- data/lib/plugins/draft.rb +58 -0
- data/lib/plugins/expand-tinyurl.rb +5 -9
- data/lib/plugins/favotter.rb +1 -1
- data/lib/plugins/footer.rb +22 -0
- data/lib/plugins/friends.rb +5 -4
- data/lib/plugins/g.rb +9 -16
- data/lib/plugins/gem_install.rb +24 -0
- data/lib/plugins/gist.rb +20 -0
- data/lib/plugins/grass.rb +1 -1
- data/lib/plugins/gyazo.rb +78 -0
- data/lib/plugins/http_server.rb +1 -1
- data/lib/plugins/hugeurl.rb +6 -13
- data/lib/plugins/irc_gw.rb +15 -11
- data/lib/plugins/me.rb +1 -1
- data/lib/plugins/notify-send.rb +1 -1
- data/lib/plugins/notify-send3.rb +1 -1
- data/lib/plugins/open.rb +1 -1
- data/lib/plugins/open_url.rb +5 -1
- data/lib/plugins/pool.rb +1 -1
- data/lib/plugins/random.rb +1 -1
- data/lib/plugins/reply_retweet.rb +42 -0
- data/lib/plugins/screen-notify.rb +1 -1
- data/lib/plugins/sl.rb +3 -3
- data/lib/plugins/storage.rb +7 -10
- data/lib/plugins/storage/sqlite3.rb +155 -0
- data/lib/plugins/storage/status.rb +2 -0
- data/lib/plugins/stream.rb +1 -1
- data/lib/plugins/tinyurl.rb +3 -9
- data/lib/plugins/trends.rb +2 -2
- data/lib/plugins/truncate.rb +1 -1
- data/lib/plugins/w3mimg.rb +1 -1
- data/lib/termtter.rb +19 -20
- data/lib/termtter/active_rubytter.rb +4 -0
- data/lib/termtter/api.rb +22 -5
- data/lib/termtter/client.rb +55 -40
- data/lib/termtter/command.rb +3 -2
- data/lib/termtter/config_setup.rb +1 -1
- data/lib/termtter/config_template.erb +5 -0
- data/lib/termtter/default_config.rb +18 -0
- data/lib/termtter/hookable.rb +1 -0
- data/lib/termtter/httppool.rb +44 -0
- data/lib/termtter/memory_cache.rb +32 -0
- data/lib/termtter/optparse.rb +8 -15
- data/lib/termtter/rubytter_proxy.rb +65 -4
- data/lib/termtter/system_extensions.rb +40 -9
- data/lib/termtter/task.rb +2 -1
- data/spec/plugins/defaults/hashtag_spec.rb +8 -7
- data/spec/plugins/defaults/list_spec.rb +33 -0
- data/spec/plugins/defaults/plugin_spec.rb +17 -0
- data/spec/plugins/defaults/retweet_spec.rb +205 -0
- data/spec/plugins/draft_spec.rb +59 -0
- data/spec/plugins/expand-tinyurl_spec.rb +21 -0
- data/spec/plugins/footer_spec.rb +50 -0
- data/spec/plugins/storage/sqlite3_spec.rb +41 -0
- data/spec/termtter/api_spec.rb +1 -1
- data/spec/termtter/client_spec.rb +21 -21
- data/spec/termtter/command_spec.rb +8 -8
- data/spec/termtter/config_spec.rb +2 -2
- data/spec/termtter/memory_cache_spec.rb +20 -0
- data/spec/termtter/optparse_spec.rb +1 -1
- data/spec/termtter/rubytter_proxy_spec.rb +38 -0
- data/spec/termtter/system_extensions_spec.rb +25 -23
- data/spec/termtter/task_manager_spec.rb +1 -1
- data/spec/termtter_spec.rb +4 -2
- metadata +88 -19
- data/lib/plugins/defaults/lists.rb +0 -14
- data/lib/plugins/irb.rb +0 -6
- data/lib/plugins/storage/DB.rb +0 -37
- data/lib/termtter/version.rb +0 -4
- data/spec/plugins/defaults/lists_spec.rb +0 -34
- data/spec/plugins/storage/DB_spec_.rb +0 -12
data/lib/plugins/confirm.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
config.plugins.crypt.set_default(:salt, 'No Termtter, No Life.')
|
6
|
+
|
7
|
+
def encrypt(msg, salt)
|
8
|
+
encoder = OpenSSL::Cipher::DES.new
|
9
|
+
encoder.encrypt
|
10
|
+
encoder.pkcs5_keyivgen(salt)
|
11
|
+
(encoder.update(msg) + encoder.final).unpack('H*').to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def decrypt(msg, salt)
|
15
|
+
decoder = OpenSSL::Cipher::DES.new
|
16
|
+
decoder.decrypt
|
17
|
+
decoder.pkcs5_keyivgen(salt)
|
18
|
+
decoder.update([msg].pack('H*')) + decoder.final
|
19
|
+
end
|
20
|
+
|
21
|
+
Termtter::Client.register_command(
|
22
|
+
:name => :crypt,
|
23
|
+
:help => ['crypt TEXT', 'Post a encrypted message'],
|
24
|
+
:exec_proc => lambda {|arg|
|
25
|
+
msg = arg
|
26
|
+
prefix = '{DES}'
|
27
|
+
status = prefix + encrypt(msg, config.plugins.crypt.salt)
|
28
|
+
Termtter::API.twitter.update(status)
|
29
|
+
puts "=> #{status}"
|
30
|
+
status
|
31
|
+
}
|
32
|
+
)
|
33
|
+
|
34
|
+
Termtter::Client::register_hook(
|
35
|
+
:name => :decrypt_message,
|
36
|
+
:point => :filter_for_output,
|
37
|
+
:exec_proc => lambda do |statuses, event|
|
38
|
+
statuses.each do |s|
|
39
|
+
s.text.gsub!(/^\{DES\}(.*)/) do |m|
|
40
|
+
"{decrypt}" + decrypt($1, config.plugins.crypt.salt)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
)
|
@@ -31,7 +31,7 @@ module Termtter
|
|
31
31
|
Client.get_hooks('prepare_command').each {|hook|
|
32
32
|
command_text = hook.call(command_text)
|
33
33
|
}
|
34
|
-
Client.
|
34
|
+
Client.execute(command_text)
|
35
35
|
rescue TimeoutError
|
36
36
|
puts TermColor.parse("<red>Time out :(</red>")
|
37
37
|
end
|
@@ -62,30 +62,47 @@ module Termtter
|
|
62
62
|
@input_thread.join
|
63
63
|
end
|
64
64
|
|
65
|
+
def do_completion(input)
|
66
|
+
input = input.sub(/^\s*/, '')
|
67
|
+
|
68
|
+
words = []
|
69
|
+
|
70
|
+
words = Client.commands.values.
|
71
|
+
inject([]) {|array, command| array + [command.name] + command.aliases}.
|
72
|
+
map(&:to_s).
|
73
|
+
grep(/^\s*#{Regexp.quote(input)}/)
|
74
|
+
|
75
|
+
if words.empty?
|
76
|
+
command = Client.find_command(input)
|
77
|
+
words = command ? command.complement(input) : []
|
78
|
+
end
|
79
|
+
|
80
|
+
if words.empty?
|
81
|
+
Client.get_hooks(:completion).each do |hook|
|
82
|
+
words << hook.call(input) rescue nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
words.flatten.compact
|
87
|
+
rescue Exception => e
|
88
|
+
Client.handle_error(e)
|
89
|
+
end
|
90
|
+
|
65
91
|
def setup_readline
|
66
92
|
if Readline.respond_to?(:basic_word_break_characters=)
|
67
93
|
Readline.basic_word_break_characters= "\t\n\"\\'`><=;|&{("
|
68
94
|
end
|
95
|
+
|
69
96
|
Readline.completion_case_fold = true
|
70
|
-
Readline.completion_proc = lambda {|input|
|
71
|
-
begin
|
72
|
-
words = Client.commands.map {|name, command| command.complement(input) }.flatten.compact
|
73
|
-
|
74
|
-
if words.empty?
|
75
|
-
Client.get_hooks(:completion).each do |hook|
|
76
|
-
words << hook.call(input) rescue nil
|
77
|
-
end
|
78
|
-
end
|
79
97
|
|
80
|
-
|
81
|
-
|
82
|
-
Client.handle_error(e)
|
83
|
-
end
|
84
|
-
}
|
98
|
+
Readline.completion_proc = lambda {|input| do_completion(input) }
|
99
|
+
|
85
100
|
vi_or_emacs = config.editing_mode
|
86
101
|
unless vi_or_emacs.empty?
|
87
102
|
Readline.__send__("#{vi_or_emacs}_editing_mode")
|
88
103
|
end
|
104
|
+
|
105
|
+
Readline.rl_parse_and_bind('TAB: menu-complete')
|
89
106
|
end
|
90
107
|
|
91
108
|
def trap_setting()
|
@@ -95,7 +112,7 @@ module Termtter
|
|
95
112
|
begin
|
96
113
|
system "stty", stty_save
|
97
114
|
ensure
|
98
|
-
Client.
|
115
|
+
Client.execute('exit')
|
99
116
|
end
|
100
117
|
end
|
101
118
|
trap("CONT") do
|
@@ -107,7 +124,7 @@ module Termtter
|
|
107
124
|
end
|
108
125
|
end
|
109
126
|
|
110
|
-
Client.register_hook(:initialize_command_line, :point => :
|
127
|
+
Client.register_hook(:initialize_command_line, :point => :init_command_line) do
|
111
128
|
CommandLine.start
|
112
129
|
end
|
113
130
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
config.set_default(:confirm, false)
|
3
|
+
|
4
|
+
def confirm(message)
|
5
|
+
if config.confirm && !Termtter::Client.confirm(message)
|
6
|
+
raise Termtter::CommandCanceled
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Termtter::RubytterProxy.register_hook(:confirm_update, :point => :pre_update) do |*args|
|
11
|
+
confirm("update #{args.first}")
|
12
|
+
args
|
13
|
+
end
|
14
|
+
|
15
|
+
Termtter::RubytterProxy.register_hook(:confirm_direct_message, :point => :pre_direct_message) do |*args|
|
16
|
+
confirm("direct #{args[0]} #{args[1]}")
|
17
|
+
args
|
18
|
+
end
|
19
|
+
|
20
|
+
Termtter::RubytterProxy.register_hook(:confirm_retweet, :point => :pre_retweet) do |*args|
|
21
|
+
status = Termtter::API.twitter.show(args.first)
|
22
|
+
confirm("retweet #{status.text}")
|
23
|
+
args
|
24
|
+
end
|
25
|
+
|
26
|
+
Termtter::RubytterProxy.register_hook(:confirm_delete, :point => :pre_remove_status) do |*args|
|
27
|
+
status = Termtter::API.twitter.show(args.first)
|
28
|
+
confirm("delete #{status.text}")
|
29
|
+
args
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'irb'
|
2
|
+
|
3
|
+
module IRB
|
4
|
+
def self.start_session(binding)
|
5
|
+
unless @__irb_initialized
|
6
|
+
IRB.setup(nil)
|
7
|
+
@__irb_initialized = true
|
8
|
+
end
|
9
|
+
|
10
|
+
workspace = WorkSpace.new(binding)
|
11
|
+
|
12
|
+
irb = Irb.new(workspace)
|
13
|
+
|
14
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
15
|
+
@CONF[:MAIN_CONTEXT] = irb.context
|
16
|
+
|
17
|
+
catch(:IRB_EXIT) do
|
18
|
+
irb.eval_input
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Termtter::Client.register_command(:irb) do |arg|
|
24
|
+
begin
|
25
|
+
completion_proc = Readline.completion_proc
|
26
|
+
IRB.start_session(binding)
|
27
|
+
ensure
|
28
|
+
Readline.completion_proc = completion_proc
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
config.plugins.keyword.set_default(
|
5
|
+
:highlight_patterns,
|
6
|
+
[
|
7
|
+
['on_cyan', 'white'],
|
8
|
+
['on_green', 'white'],
|
9
|
+
['on_magenta', 'white'],
|
10
|
+
['on_red', 'white'],
|
11
|
+
['on_blue', 'white'],
|
12
|
+
['on_black', 'white'],
|
13
|
+
['on_white', 'white'],
|
14
|
+
['on_yellow', 'white'],
|
15
|
+
]
|
16
|
+
)
|
17
|
+
|
18
|
+
config.plugins.keyword.set_default(:keywords, [])
|
19
|
+
|
20
|
+
module Termtter::Client
|
21
|
+
public_storage[:keywords] ||= Set.new(config.plugins.keyword.keywords)
|
22
|
+
|
23
|
+
register_hook :highlight_keywords, :point => :pre_coloring do |text, event|
|
24
|
+
public_storage[:keywords].each_with_index do |keyword, index|
|
25
|
+
highlight_pattern = config.plugins.keyword.highlight_patterns[index % config.plugins.keyword.highlight_patterns.size]
|
26
|
+
text = text.gsub(
|
27
|
+
/(#{Regexp.quote(keyword)})/i,
|
28
|
+
"<#{highlight_pattern[0]}><#{highlight_pattern[1]}>" +
|
29
|
+
"\\1" +
|
30
|
+
"</#{highlight_pattern[1]}></#{highlight_pattern[0]}>"
|
31
|
+
)
|
32
|
+
end
|
33
|
+
text
|
34
|
+
end
|
35
|
+
|
36
|
+
register_command(
|
37
|
+
'keyword add',
|
38
|
+
:help => ['keyword add KEYWORD', 'Add a highlight keyword']
|
39
|
+
) do |args|
|
40
|
+
args.split(/\s+/).each do |arg|
|
41
|
+
public_storage[:keywords] << arg
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
register_command(
|
46
|
+
'keyword clear',
|
47
|
+
:help => ['keyword clear', 'Clear highlight keywords']
|
48
|
+
) do |args|
|
49
|
+
public_storage[:keywords].clear
|
50
|
+
end
|
51
|
+
|
52
|
+
register_command(
|
53
|
+
'keyword list',
|
54
|
+
:help => ['keyword list', 'List highlight keywords']
|
55
|
+
) do |args|
|
56
|
+
p public_storage[:keywords].to_a
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
module Termtter::Client
|
2
|
+
public_storage[:lists] = []
|
3
|
+
|
4
|
+
register_hook(:fetch_my_lists, :point => :launched) do
|
5
|
+
begin
|
6
|
+
public_storage[:lists] +=
|
7
|
+
Termtter::API.twitter.lists(config.user_name).lists.map(&:full_name)
|
8
|
+
rescue TimeoutError
|
9
|
+
# do nothing
|
10
|
+
rescue Exception => e
|
11
|
+
Termtter::Client.handle_error(e)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
register_command(
|
16
|
+
:name => :list, :aliases => [:l],
|
17
|
+
:exec_proc => lambda {|arg|
|
18
|
+
if arg =~ /\-([\d]+)/
|
19
|
+
options = {:count => $1}
|
20
|
+
arg = arg.gsub(/\-([\d]+)/, '')
|
21
|
+
else
|
22
|
+
options = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
last_error = nil
|
26
|
+
if arg.empty?
|
27
|
+
event = :list_friends_timeline
|
28
|
+
statuses = Termtter::API.twitter.home_timeline(options)
|
29
|
+
else
|
30
|
+
event = :list_user_timeline
|
31
|
+
statuses = []
|
32
|
+
Array(arg.split).each do |user|
|
33
|
+
if user =~ /\/\w+/
|
34
|
+
user_name, slug = *user.split('/')
|
35
|
+
user_name = config.user_name if user_name.empty?
|
36
|
+
user_name = normalize_as_user_name(user_name)
|
37
|
+
options[:per_page] = options[:count]
|
38
|
+
options.delete(:count)
|
39
|
+
statuses += Termtter::API.twitter.list_statuses(user_name, slug, options)
|
40
|
+
else
|
41
|
+
begin
|
42
|
+
if user =~ /^\d+$/
|
43
|
+
profile = Termtter::API.twitter.user(nil, :screen_name => user) rescue nil
|
44
|
+
unless profile
|
45
|
+
status = Termtter::API.twitter.show(user) rescue nil
|
46
|
+
user = status.user.screen_name if status
|
47
|
+
end
|
48
|
+
end
|
49
|
+
user_name = normalize_as_user_name(user.sub(/\/$/, ''))
|
50
|
+
statuses += Termtter::API.twitter.user_timeline(user_name, options)
|
51
|
+
rescue Rubytter::APIError => e
|
52
|
+
last_error = e
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
output(statuses, event)
|
58
|
+
raise last_error if last_error
|
59
|
+
},
|
60
|
+
:help => ["list,l [USERNAME]/[SLUG] [-COUNT]", "List the posts"]
|
61
|
+
)
|
62
|
+
|
63
|
+
register_command(
|
64
|
+
:name => 'list list',
|
65
|
+
:exec => lambda {|arg|
|
66
|
+
unless arg.empty?
|
67
|
+
user_name = normalize_as_user_name(arg)
|
68
|
+
else
|
69
|
+
user_name = config.user_name
|
70
|
+
end
|
71
|
+
# TODO: show more information of lists
|
72
|
+
lists = Termtter::API.twitter.lists(user_name).lists
|
73
|
+
public_storage[:lists] += lists.map(&:full_name)
|
74
|
+
puts lists.map{|i| i.full_name}.join("\n")
|
75
|
+
},
|
76
|
+
:help => ["lists [USERNAME]", "Show Lists"]
|
77
|
+
)
|
78
|
+
|
79
|
+
register_command(
|
80
|
+
:name => %s{list follow},
|
81
|
+
:alias => %s{list add},
|
82
|
+
:exec => lambda { |arg|
|
83
|
+
list_name, *users = arg.split(' ')
|
84
|
+
slug = list_name_to_slug(list_name)
|
85
|
+
users.each{ |screen_name|
|
86
|
+
begin
|
87
|
+
user = Termtter::API.twitter.cached_user(screen_name) || Termtter::API.twitter.user(screen_name)
|
88
|
+
Termtter::API.twitter.add_member_to_list(slug, user.id)
|
89
|
+
puts "#{slug} + #{screen_name}"
|
90
|
+
rescue => e
|
91
|
+
handle_error(e)
|
92
|
+
end
|
93
|
+
}
|
94
|
+
},
|
95
|
+
:help => ["list follow SLUG USERNAME", "Follow users to the list"]
|
96
|
+
)
|
97
|
+
|
98
|
+
register_command(
|
99
|
+
:name => %s{list remove},
|
100
|
+
:exec => lambda { |arg|
|
101
|
+
list_name, *users = arg.split(' ')
|
102
|
+
slug = list_name_to_slug(list_name)
|
103
|
+
users.each{ |screen_name|
|
104
|
+
begin
|
105
|
+
user = Termtter::API.twitter.cached_user(screen_name) || Termtter::API.twitter.user(screen_name)
|
106
|
+
Termtter::API.twitter.remove_member_from_list(slug, user.id)
|
107
|
+
puts "#{slug} - #{screen_name}"
|
108
|
+
rescue => e
|
109
|
+
handle_error(e)
|
110
|
+
end
|
111
|
+
}
|
112
|
+
},
|
113
|
+
:help => ["list remove SLUG USERNAME", "Remove user(s) from the list"]
|
114
|
+
)
|
115
|
+
|
116
|
+
register_command(
|
117
|
+
:name => %s{list create},
|
118
|
+
:exec => lambda { |arg|
|
119
|
+
slug, *options = arg.split(' ')
|
120
|
+
param = { }
|
121
|
+
|
122
|
+
OptionParser.new {|opt|
|
123
|
+
opt.on('--description VALUE') {|v| param[:description] = v }
|
124
|
+
opt.on('--private') {|v| param[:mode] = 'private' }
|
125
|
+
opt.parse(options)
|
126
|
+
}
|
127
|
+
list = Termtter::API.twitter.create_list(slug, param)
|
128
|
+
public_storage[:lists] << list.full_name
|
129
|
+
p [list.full_name, param]
|
130
|
+
},
|
131
|
+
:help => ["list create SLUG [--description VALUE] [--private]", "Create list"]
|
132
|
+
)
|
133
|
+
|
134
|
+
register_command(
|
135
|
+
:name => %s{list delete},
|
136
|
+
:exec => lambda { |arg|
|
137
|
+
return unless confirm("Are you sure?")
|
138
|
+
arg.split(' ').each{ |list_name|
|
139
|
+
begin
|
140
|
+
slug = list_name_to_slug(list_name)
|
141
|
+
list = Termtter::API.twitter.delete_list(slug)
|
142
|
+
public_storage[:lists].delete(list.full_name)
|
143
|
+
puts "#{list.full_name} deleted"
|
144
|
+
rescue => e
|
145
|
+
handle_error(e)
|
146
|
+
end
|
147
|
+
}
|
148
|
+
},
|
149
|
+
:help => ["list delete SLUG", "Delete list"]
|
150
|
+
)
|
151
|
+
|
152
|
+
def self.list_name_to_slug(list_name)
|
153
|
+
list_name[/([^\/]*)$/]
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Termtter::Client
|
4
|
+
register_command('plugin edit') do |arg|
|
5
|
+
if /\-s/ =~ arg
|
6
|
+
arg = arg.sub('-s', '').strip
|
7
|
+
include_system_plugins = true
|
8
|
+
end
|
9
|
+
|
10
|
+
if path = search_plugin_file(arg, include_system_plugins)
|
11
|
+
open_editor(path)
|
12
|
+
plug(arg)
|
13
|
+
puts "reload => #{arg}"
|
14
|
+
else
|
15
|
+
puts TermColor.parse('<red>Plugin not found :(</red>')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
register_command('plugin show') do |arg|
|
20
|
+
if path = search_plugin_file(arg, true)
|
21
|
+
puts IO.read(path)
|
22
|
+
else
|
23
|
+
puts TermColor.parse('<red>Plugin not found :(</red>')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
register_command('plugin create') do |arg|
|
28
|
+
path = "#{Termtter::CONF_DIR}/plugins/#{arg}.rb"
|
29
|
+
unless File.exists?(path)
|
30
|
+
FileUtils.mkdir_p(File.dirname(path))
|
31
|
+
# TODO: insert plugin template to plugin file
|
32
|
+
open_editor(path)
|
33
|
+
plug(arg)
|
34
|
+
puts "load => #{arg}"
|
35
|
+
else
|
36
|
+
puts TermColor.parse('<red>The plugin already exists :(</red>')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.open_editor(path)
|
41
|
+
# TODO: change to common method or use launchy
|
42
|
+
system ENV['EDITOR'] || 'vim', path
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.search_plugin_file(name, include_system_plugins = false)
|
46
|
+
regex = /#{Regexp.quote(name + '.rb')}$/
|
47
|
+
plugin_files(include_system_plugins).detect {|f| regex =~ f}
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.plugin_files(include_system_plugins = false)
|
51
|
+
files = Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]
|
52
|
+
files += Dir["#{File.expand_path(File.dirname(__FILE__))}/*.rb"] if include_system_plugins
|
53
|
+
files
|
54
|
+
end
|
55
|
+
|
56
|
+
# TODO: rename command 'plug' to 'plugin load' and define 'plug' as alias
|
57
|
+
# TODO: completion for plugin names
|
58
|
+
end
|
59
|
+
|