jugyo-termtter 1.0.3 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/Rakefile +1 -1
  2. data/lib/plugins/addspace.rb +27 -0
  3. data/lib/plugins/bomb.rb +9 -12
  4. data/lib/plugins/expand-tinyurl.rb +12 -3
  5. data/lib/plugins/group.rb +10 -6
  6. data/lib/plugins/growl.rb +3 -3
  7. data/lib/plugins/history.rb +21 -10
  8. data/lib/plugins/log.rb +10 -10
  9. data/lib/plugins/msagent.rb +23 -11
  10. data/lib/plugins/notify-send.rb +17 -12
  11. data/lib/plugins/plugin.rb +1 -1
  12. data/lib/plugins/say.rb +8 -6
  13. data/lib/plugins/scrape.rb +1 -1
  14. data/lib/plugins/screen-notify.rb +17 -10
  15. data/lib/plugins/standard_plugins.rb +30 -19
  16. data/lib/plugins/stdout.rb +35 -54
  17. data/lib/plugins/storage/status.rb +23 -20
  18. data/lib/plugins/storage.rb +17 -23
  19. data/lib/plugins/update_editor.rb +1 -1
  20. data/lib/plugins/uri-open.rb +7 -5
  21. data/lib/plugins/url_addspace.rb +1 -1
  22. data/lib/termtter/api.rb +2 -1
  23. data/lib/termtter/client.rb +90 -118
  24. data/lib/termtter/command.rb +6 -1
  25. data/lib/termtter/hook.rb +7 -2
  26. data/lib/termtter/system_extensions.rb +15 -10
  27. data/lib/termtter/version.rb +1 -1
  28. data/lib/termtter.rb +11 -0
  29. data/spec/{plugin → plugins}/cool_spec.rb +0 -0
  30. data/spec/{plugin → plugins}/english_spec.rb +0 -0
  31. data/spec/{plugin → plugins}/favorite_spec.rb +0 -0
  32. data/spec/{plugin → plugins}/fib_spec.rb +0 -0
  33. data/spec/{plugin → plugins}/filter_spec.rb +0 -0
  34. data/spec/{plugin → plugins}/pause_spec.rb +0 -0
  35. data/spec/{plugin → plugins}/plugin_spec.rb +0 -0
  36. data/spec/{plugin → plugins}/primes_spec.rb +0 -0
  37. data/spec/{plugin → plugins}/shell_spec.rb +0 -0
  38. data/spec/{plugin → plugins}/sl_spec.rb +0 -0
  39. data/spec/{plugin → plugins}/spam_spec.rb +0 -0
  40. data/spec/{plugin → plugins}/standard_plugins_spec.rb +0 -0
  41. data/spec/{plugin → plugins}/storage/DB_spec.rb +0 -0
  42. data/spec/{plugin → plugins}/storage/status_spec.rb +1 -1
  43. data/spec/termtter/client_spec.rb +5 -8
  44. data/spec/termtter/command_spec.rb +10 -10
  45. metadata +18 -17
@@ -7,42 +7,45 @@ module Termtter::Storage
7
7
  class Status
8
8
  KEYS = %w[post_id created_at in_reply_to_status_id in_reply_to_user_id post_text user_id screen_name]
9
9
 
10
- def size
10
+ def self.size
11
11
  DB.instance.db.get_first_value("select count(*) from post").to_i
12
12
  end
13
13
 
14
14
  def self.search(query)
15
15
  raise "query must be Hash(#{query}, #{query.class})" unless query.kind_of? Hash
16
-
17
- DB.instance.db.execute("select created_at, screen_name, post_text, in_reply_to_status_id, post_id from post inner join user on post.user_id = user.id where post_text like '%' || ? || '%' ", query[:post_text]) do |created_at, screen_name, post_text, in_reply_to_status_id, post_id|
18
-
19
- # DB.instance.db.execute("select created_at, screen_name, post_text, in_reply_to_status_id, post_id from post inner join user on post.user_id = user.id where post_text like '%of%' ", query[:post_text]) do |created_at, screen_name, post_text, in_reply_to_status_id, post_id|
20
- p [created_at, screen_name, post_text, in_reply_to_status_id, post_id]
16
+ result = []
17
+ DB.instance.db.execute("select created_at, screen_name, post_text, in_reply_to_status_id, post_id, user_id from post inner join user on post.user_id = user.id where post_text like '%' || ? || '%' ",
18
+ query[:text]) do |created_at, screen_name, post_text, in_reply_to_status_id, post_id, user_id|
19
+ created_at = Time.at(created_at).to_s
20
+ result << {
21
+ :id => post_id,
22
+ :created_at => created_at,
23
+ :text => post_text,
24
+ :in_reply_to_status_id => in_reply_to_status_id,
25
+ :in_reply_to_user_id => nil,
26
+ :user => {
27
+ :id => user_id,
28
+ :screen_name => screen_name
29
+ }
30
+ }
21
31
  end
32
+ Rubytter.json_to_struct(result)
22
33
  end
23
34
 
24
35
  def self.insert(data)
25
- raise "data must be Hash(#{data}, #{data.class})" unless data.kind_of? Hash
26
- # 条件しぼりたいけどやりかたがうまくわからない
27
- # raise "unko" unless data.keys.all?{|c| KEYS.include? c}
28
- begin
29
36
  DB.instance.db.execute(
30
37
  "insert into post values(?,?,?,?,?,?)",
31
38
  data[:post_id],
32
39
  data[:created_at],
33
40
  data[:in_reply_to_status_id],
34
41
  data[:in_reply_to_user_id],
35
- data[:post_text],
42
+ data[:text],
36
43
  data[:user_id])
37
- begin
38
- DB.instance.db.execute(
39
- "insert into user values(?,?)",
40
- data[:user_id],
41
- data[:screen_name])
42
- rescue # FIXME: specify exceptions here
43
- end
44
- rescue # FIXME: specify exceptions here
45
- end
44
+ DB.instance.db.execute(
45
+ "insert into user values(?,?)",
46
+ data[:user_id],
47
+ data[:screen_name])
48
+ rescue SQLite3::SQLException
46
49
  end
47
50
  end
48
51
  end
@@ -8,40 +8,34 @@ require File.dirname(__FILE__) + '/storage/status'
8
8
  module Termtter::Client
9
9
  public_storage[:log] = []
10
10
 
11
- add_hook do |statuses, event|
12
- case event
13
- when :pre_filter
11
+ register_hook(
12
+ :name => :storage,
13
+ :points => [:pre_filter],
14
+ :exec_proc => lambda {|statuses, event|
14
15
  statuses.each do |s|
15
16
  Termtter::Storage::Status.insert(
16
17
  :post_id => s.id,
17
18
  :created_at => Time.parse(s.created_at).to_i,
18
19
  :in_reply_to_status_id => s.in_reply_to_status_id,
19
20
  :in_reply_to_user_id => s.in_reply_to_user_id,
20
- :post_text => s.text,
21
+ :post => s.text,
21
22
  :user_id => s.user.id,
22
- :screen_name => s.user.screen_name)
23
+ :screen_name => s.user.screen_name
24
+ )
23
25
  end
24
- end
25
- end
26
+ }
27
+ )
26
28
 
27
29
  register_command(
28
- :name => :search_storage, :aliases => [:ss],
30
+ :name => :search_storage,
31
+ :aliases => [:ss],
29
32
  :exec_proc => lambda {|arg|
30
33
  unless arg.strip.empty?
31
34
  key = arg.strip
32
- Termtter::Storage::Status.search({ :post_text => key})
33
- =begin
34
- statuses = public_storage[:storage].search({ :post_text => key})
35
-
36
- statuses.each do |s|
37
- p s
38
- end
39
- call_hooks(statuses, :search)
40
- =end
41
- end
42
-
43
- },
44
-
45
- :help => [ 'search_storage WORD', 'Search storage for WORD' ]
46
- )
35
+ statuses = Termtter::Storage::Status.search({:text => key})
36
+ output(statuses, :search)
37
+ end
38
+ },
39
+ :help => [ 'search_storage WORD', 'Search storage for WORD' ]
40
+ )
47
41
  end
@@ -8,7 +8,7 @@ module Termtter::Client
8
8
  else
9
9
  config.plugins.update_editor.set_default('editor', 'vi')
10
10
  end
11
- config.plugins.update_editor.set_default('add_completion', false)
11
+ config.plugins.update_editor.set_default('add_completion', true)
12
12
 
13
13
 
14
14
  def self.input_editor
@@ -3,13 +3,15 @@
3
3
  module Termtter::Client
4
4
  public_storage[:uris] = []
5
5
 
6
- add_hook do |statuses, event, t|
7
- if event == :update_friends_timeline
6
+ register_hook(
7
+ :name => :uri_open,
8
+ :points => [:post_filter],
9
+ :exec_proc => lambda {|statuses, event|
8
10
  statuses.each do |s|
9
- public_storage[:uris] += s.text.scan(%r|https?://[^\s]+|)
11
+ public_storage[:uris] += s[:text].scan(%r|https?://[^\s]+|)
10
12
  end
11
- end
12
- end
13
+ }
14
+ )
13
15
 
14
16
  def self.open_uri(uri)
15
17
  unless config.plugins.uri_open.browser.empty?
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Termtter::Client
4
- add_filter do |statuses|
4
+ add_filter do |statuses, event|
5
5
  statuses.each do |s|
6
6
  s.text.gsub!(/(\S)(https?:\/\/)/, '\1 \2')
7
7
  end
data/lib/termtter/api.rb CHANGED
@@ -19,12 +19,13 @@ module Termtter
19
19
  config.user_name,
20
20
  config.password,
21
21
  {
22
+ :app_name => Termtter::APP_NAME,
22
23
  :host => config.host,
23
24
  :header => {
24
25
  'User-Agent' => 'Termtter http://github.com/jugyo/termtter',
25
26
  'X-Twitter-Client' => 'Termtter',
26
27
  'X-Twitter-Client-URL' => 'http://github.com/jugyo/termtter',
27
- 'X-Twitter-Client-Version' => '0.1'
28
+ 'X-Twitter-Client-Version' => Termtter::VERSION
28
29
  },
29
30
  :enable_ssl => config.enable_ssl,
30
31
  :proxy_host => config.proxy.host,
@@ -1,15 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require 'fileutils'
3
+ require 'logger'
3
4
 
4
5
  module Termtter
5
- APP_NAME = 'termtter'
6
-
7
- config.system.set_default :conf_dir, File.expand_path('~/.termtter')
8
- CONF_DIR = config.system.conf_dir
9
-
10
- config.system.set_default :conf_file, CONF_DIR + '/config'
11
- CONF_FILE = config.system.conf_file
12
- $:.unshift(Termtter::CONF_DIR)
13
6
 
14
7
  class CommandNotFound < StandardError; end
15
8
 
@@ -18,15 +11,14 @@ module Termtter
18
11
  class << self
19
12
 
20
13
  def init
21
- @@hooks = []
22
- @@new_hooks = {}
23
- @@new_commands = {}
24
- @@completions = []
25
- @@filters = []
26
- @@helps = []
27
- @@since_id = nil
28
- @@input_thread = nil
29
- @@task_manager = Termtter::TaskManager.new
14
+ @hooks = {}
15
+ @commands = {}
16
+ @filters = []
17
+ @since_id = nil
18
+ @input_thread = nil
19
+ @task_manager = Termtter::TaskManager.new
20
+ config.log.set_default(:logger, nil)
21
+ config.log.set_default(:level, nil)
30
22
  config.set_default(:update_interval, 300)
31
23
  config.set_default(:prompt, '> ')
32
24
  config.set_default(:devel, false)
@@ -34,15 +26,15 @@ module Termtter
34
26
  end
35
27
 
36
28
  def public_storage
37
- @@public_storage ||= {}
29
+ @public_storage ||= {}
38
30
  end
39
31
 
40
- %w[hook completion filter].each do |n|
41
- eval <<-EOF
42
- def add_#{n}(&b)
43
- @@#{n}s << b
44
- end
45
- EOF
32
+ def add_filter(&b)
33
+ @filters << b
34
+ end
35
+
36
+ def clear_filter
37
+ @filters.clear
46
38
  end
47
39
 
48
40
  def register_hook(arg)
@@ -54,15 +46,15 @@ module Termtter
54
46
  else
55
47
  raise ArgumentError, 'must be given Termtter::Hook or Hash'
56
48
  end
57
- @@new_hooks[hook.name] = hook
49
+ @hooks[hook.name] = hook
58
50
  end
59
51
 
60
52
  def get_hook(name)
61
- @@new_hooks[name]
53
+ @hooks[name]
62
54
  end
63
55
 
64
56
  def get_hooks(point)
65
- @@new_hooks.values.select do |hook|
57
+ @hooks.values.select do |hook|
66
58
  hook.match?(point)
67
59
  end
68
60
  end
@@ -76,11 +68,11 @@ module Termtter
76
68
  else
77
69
  raise ArgumentError, 'must be given Termtter::Command or Hash'
78
70
  end
79
- @@new_commands[command.name] = command
71
+ @commands[command.name] = command
80
72
  end
81
73
 
82
74
  def get_command(name)
83
- @@new_commands[name]
75
+ @commands[name]
84
76
  end
85
77
 
86
78
  def register_macro(name, macro, options = {})
@@ -91,58 +83,44 @@ module Termtter
91
83
  register_command(command)
92
84
  end
93
85
 
94
- def add_help(name, desc)
95
- @@helps << [name, desc]
96
- end
97
-
98
- %w[hooks completions helps filters].each do |n|
99
- eval <<-EOF
100
- def clear_#{n}
101
- @@#{n}.clear
102
- end
103
- EOF
86
+ # statuses => [status, status, ...]
87
+ # status => {
88
+ # :id => status id,
89
+ # :created_at => created time,
90
+ # :user_id => user id,
91
+ # :name => user name,
92
+ # :screen_name => user screen_name,
93
+ # :source => source,
94
+ # :reply_to => reply_to status id,
95
+ # :text => status,
96
+ # :original_data => original data,
97
+ # }
98
+ def output(statuses, event)
99
+ return if statuses.nil? || statuses.empty?
100
+
101
+ statuses = statuses.sort_by{|s|s.id}
102
+ call_hooks(:pre_filter, statuses, event)
103
+ filtered = apply_filters(statuses, event)
104
+ call_hooks(:post_filter, filtered, event)
105
+ call_hooks(:output, filtered, event)
104
106
  end
105
107
 
106
- # memo: each filter must return Array of Status
107
- def apply_filters(result, event = nil)
108
- case event
109
- when :show
110
- result
111
- when :search
112
- filtered = result.results.map(&:dup)
113
- @@filters.each do |f|
114
- filtered = f.call(filtered, event)
115
- end
116
- result.results = filtered
117
- result
118
- else
119
- filtered = result.map(&:dup)
120
- @@filters.each do |f|
108
+ def apply_filters(statuses, event)
109
+ filtered = statuses.map(&:dup)
110
+ @filters.each do |f|
121
111
  filtered = f.call(filtered, event)
122
112
  end
123
113
  filtered
124
- end
125
- rescue => e
126
- handle_error(e)
127
- result
128
- end
129
-
130
- def do_hooks(statuses, event)
131
- @@hooks.each do |h|
132
- begin
133
- h.call(statuses.dup, event, Termtter::API.twitter)
134
- rescue => e
135
- handle_error(e)
136
- end
137
- end
114
+ rescue => e
115
+ handle_error(e)
138
116
  end
139
117
 
140
118
  # return last hook return value
141
- def call_new_hooks(point, *args)
119
+ def call_hooks(point, *args)
142
120
  result = nil
143
121
  get_hooks(point).each {|hook|
144
122
  break if result == false # interrupt if hook return false
145
- result = hook.exec_proc.call(*args)
123
+ result = hook.call(*args)
146
124
  }
147
125
  result
148
126
  rescue => e
@@ -153,36 +131,29 @@ module Termtter
153
131
  end
154
132
  end
155
133
 
156
- # TODO: delete argument "tw" when unnecessary
157
- def call_hooks(statuses, event, tw = nil)
158
- do_hooks(statuses, :pre_filter)
159
- filtered = apply_filters(statuses, event)
160
- do_hooks(filtered, :post_filter)
161
- do_hooks(filtered, event)
162
- end
163
-
164
134
  def call_commands(text, tw = nil)
165
135
  return if text.empty?
166
136
 
167
137
  command_found = false
168
- @@new_commands.each do |key, command|
138
+ @commands.each do |key, command|
139
+ # match? メソッドがなんかきもちわるいので変える予定
169
140
  command_str, command_arg = command.match?(text)
170
141
  if command_str
171
142
  command_found = true
172
143
 
173
- modified_arg = call_new_hooks(
144
+ modified_arg = call_hooks(
174
145
  "modify_arg_for_#{command.name.to_s}",
175
146
  command_str,
176
147
  command_arg) || command_arg || ''
177
148
 
178
- @@task_manager.invoke_and_wait do
149
+ @task_manager.invoke_and_wait do
179
150
 
180
- pre_exec_hook_result = call_new_hooks("pre_exec_#{command.name.to_s}", command_str, modified_arg)
151
+ pre_exec_hook_result = call_hooks("pre_exec_#{command.name.to_s}", command_str, modified_arg)
181
152
  next if pre_exec_hook_result == false
182
153
  # exec command
183
- result = command.execute(modified_arg)
154
+ result = command.call(modified_arg)
184
155
  if result
185
- call_new_hooks("post_exec_#{command.name.to_s}", command_str, modified_arg, result)
156
+ call_hooks("post_exec_#{command.name.to_s}", command_str, modified_arg, result)
186
157
  end
187
158
 
188
159
  end
@@ -193,24 +164,23 @@ module Termtter
193
164
  end
194
165
 
195
166
  def pause
196
- @@task_manager.pause
167
+ @task_manager.pause
197
168
  end
198
169
 
199
170
  def resume
200
- @@task_manager.resume
171
+ @task_manager.resume
201
172
  end
202
173
 
203
174
  def add_task(*arg, &block)
204
- @@task_manager.add_task(*arg, &block)
175
+ @task_manager.add_task(*arg, &block)
205
176
  end
206
177
 
207
178
  def exit
208
179
  puts 'finalizing...'
209
180
 
210
- call_hooks([], :exit)
211
- call_new_hooks(:exit)
212
- @@task_manager.kill
213
- @@input_thread.kill if @@input_thread
181
+ call_hooks(:exit)
182
+ @task_manager.kill
183
+ @input_thread.kill if @input_thread
214
184
  end
215
185
 
216
186
  def load_default_plugins
@@ -246,7 +216,7 @@ module Termtter
246
216
  Termtter::CONF_FILE)
247
217
  end
248
218
 
249
- def pre_config_load()
219
+ def post_config_load()
250
220
  if config.system.devel
251
221
  plugin 'devel'
252
222
  end
@@ -258,14 +228,7 @@ module Termtter
258
228
  end
259
229
  Readline.completion_proc = lambda {|input|
260
230
  begin
261
- # FIXME: when migrate to Termtter::Command
262
- completions = @@completions.map {|completion|
263
- completion.call(input)
264
- }
265
- completions += @@new_commands.map {|name, command|
266
- command.complement(input)
267
- }
268
- completions.flatten.compact
231
+ @commands.map {|name, command| command.complement(input) }.flatten.compact
269
232
  rescue => e
270
233
  handle_error(e)
271
234
  end
@@ -276,19 +239,20 @@ module Termtter
276
239
  end
277
240
  end
278
241
 
242
+ # TODO: Make pluggable
279
243
  def setup_update_timeline_task()
280
244
  register_command(
281
245
  :name => :_update_timeline,
282
246
  :exec_proc => lambda {|arg|
283
247
  begin
284
- args = @@since_id ? [{:since_id => @@since_id}] : []
248
+ args = @since_id ? [{:since_id => @since_id}] : []
285
249
  statuses = Termtter::API.twitter.friends_timeline(*args)
286
250
  unless statuses.empty?
287
- @@since_id = statuses[0].id
251
+ print "\e[1K\e[0G" unless win?
252
+ @since_id = statuses[0].id
253
+ output(statuses, :update_friends_timeline)
254
+ Readline.refresh_line
288
255
  end
289
- call_hooks(statuses, :update_friends_timeline)
290
- Readline.refresh_line
291
- statuses
292
256
  rescue OpenURI::HTTPError => e
293
257
  if e.message == '401 Unauthorized'
294
258
  puts 'Could not login'
@@ -299,9 +263,11 @@ module Termtter
299
263
  }
300
264
  )
301
265
 
302
- add_task(:name => :update_timeline, :interval => config.update_interval) do
266
+ add_task(:name => :update_timeline, :interval => config.update_interval, :after => config.update_interval) do
303
267
  call_commands('_update_timeline')
304
268
  end
269
+
270
+ call_commands('_update_timeline')
305
271
  end
306
272
 
307
273
  def trap_setting()
@@ -321,9 +287,9 @@ module Termtter
321
287
  def start_input_thread
322
288
  setup_readline()
323
289
  trap_setting()
324
- @@input_thread = Thread.new do
290
+ @input_thread = Thread.new do
325
291
  while buf = Readline.readline(ERB.new(config.prompt).result(API.twitter.__send__(:binding)), true)
326
- Readline::HISTORY.pop if /^(u|update)\s+(.+)$/ =~ buf
292
+ Readline::HISTORY.pop if buf.empty?
327
293
  begin
328
294
  call_commands(buf)
329
295
  rescue CommandNotFound => e
@@ -334,30 +300,36 @@ module Termtter
334
300
  end
335
301
  end
336
302
  end
337
- @@input_thread.join
303
+ @input_thread.join
338
304
  end
339
305
 
340
- def run
341
- puts 'initializing...'
306
+ def logger
307
+ @logger
308
+ end
309
+
310
+ def setup_logger
311
+ @logger = config.log.logger || Logger.new(STDOUT)
312
+ @logger.level = config.log.level || Logger::WARN
313
+ end
342
314
 
315
+ def run
343
316
  load_default_plugins()
344
317
  load_config()
345
318
  Termtter::API.setup()
346
- pre_config_load()
319
+ setup_logger()
320
+ post_config_load()
347
321
 
348
- call_hooks([], :initialize)
349
- call_new_hooks(:initialize)
322
+ call_hooks(:initialize)
350
323
 
351
324
  setup_update_timeline_task()
352
- call_commands('_update_timeline')
353
325
 
354
- @@task_manager.run()
326
+ @task_manager.run()
355
327
  start_input_thread()
356
328
  end
357
329
 
358
330
  def handle_error(e)
359
- call_new_hooks("on_error", e)
360
- rescue => e
331
+ call_hooks("on_error", e)
332
+ rescue Exception => e
361
333
  puts "Error: #{e}"
362
334
  puts e.backtrace.join("\n")
363
335
  end
@@ -14,6 +14,10 @@ module Termtter
14
14
  # help: help text for the command (Optional)
15
15
  def initialize(args)
16
16
  raise ArgumentError, ":name is not given." unless args.has_key?(:name)
17
+ args[:exec_proc] ||= args[:exec]
18
+ args[:completion_proc] ||= args[:completion]
19
+ args[:aliases] ||= [args[:alias]].compact
20
+
17
21
  cfg = {
18
22
  :aliases => [],
19
23
  :exec_proc => lambda {|arg| },
@@ -44,7 +48,7 @@ module Termtter
44
48
  end
45
49
  end
46
50
 
47
- def execute(arg)
51
+ def call(arg)
48
52
  arg = case arg
49
53
  when nil
50
54
  ''
@@ -57,6 +61,7 @@ module Termtter
57
61
  end
58
62
 
59
63
  # return array like [command, arg]
64
+ # match? メソッドがなんかきもちわるいので変える予定
60
65
  def match?(input)
61
66
  if pattern =~ input
62
67
  [$2 || $3, $4] # $2 or $3 => command, $4 => argument
data/lib/termtter/hook.rb CHANGED
@@ -7,8 +7,8 @@ module Termtter
7
7
  def initialize(args)
8
8
  raise ArgumentError, ":name is not given." unless args.has_key?(:name)
9
9
  @name = args[:name].to_sym
10
- @points = args[:points] ? args[:points].map {|i| i } : []
11
- @exec_proc = args[:exec_proc] || lambda {}
10
+ @points = args[:points] || [args[:point]].compact
11
+ @exec_proc = args[:exec_proc] || args[:exec] || lambda {}
12
12
  end
13
13
 
14
14
  def match?(point)
@@ -23,5 +23,10 @@ module Termtter
23
23
  end
24
24
  }.empty?
25
25
  end
26
+
27
+ # TODO: need spec
28
+ def call(*args)
29
+ self.exec_proc.call(*args)
30
+ end
26
31
  end
27
32
  end
@@ -6,13 +6,8 @@ def plugin(name, init = {})
6
6
  config.plugins.__refer__(name.to_sym).__assign__(key.to_sym, value)
7
7
  end
8
8
  end
9
- # FIXME: below path should be replaced by optparsed path
10
- if File.exist?(path = File.expand_path("~/.termtter/plugins/#{name}"))
11
- require path
12
- else
13
- require "plugins/#{name}"
14
- end
15
- rescue LoadError => e
9
+ load "plugins/#{name}.rb"
10
+ rescue Exception => e
16
11
  Termtter::Client.handle_error(e)
17
12
  end
18
13
 
@@ -25,14 +20,24 @@ require 'dl/import'
25
20
  module Readline
26
21
  begin
27
22
  module LIBREADLINE
28
- extend DL::Importable
29
- dlload '/opt/local/lib/libreadline.dylib' # TODO: 環境によってパスを変える必要あり。どうやったらいいかはこれから調べる。
23
+ if DL.const_defined? :Importable
24
+ extend DL::Importable
25
+ else
26
+ extend DL::Importer
27
+ end
28
+ pathes = Array(ENV['TERMTTER_EXT_LIB'] || [
29
+ '/opt/local/lib/libreadline.dylib',
30
+ '/usr/lib/libreadline.so',
31
+ '/usr/local/lib/libreadline.so',
32
+ File.join(Gem.bindir, 'readline.dll')
33
+ ])
34
+ dlload(pathes.find { |path| File.exist?(path)})
30
35
  extern 'int rl_refresh_line(int, int)'
31
36
  end
32
37
  def self.refresh_line
33
38
  LIBREADLINE.rl_refresh_line(0, 0)
34
39
  end
35
- rescue RuntimeError, NameError
40
+ rescue Exception
36
41
  def self.refresh_line;end
37
42
  end
38
43
  end
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  module Termtter
3
- VERSION = '1.0.3'
3
+ VERSION = '1.0.6'
4
4
  end
data/lib/termtter.rb CHANGED
@@ -25,3 +25,14 @@ require 'termtter/task_manager'
25
25
  require 'termtter/client'
26
26
  require 'termtter/api'
27
27
  require 'termtter/system_extensions'
28
+
29
+ module Termtter
30
+ APP_NAME = 'termtter'
31
+
32
+ config.system.set_default :conf_dir, File.expand_path('~/.termtter')
33
+ CONF_DIR = config.system.conf_dir
34
+
35
+ config.system.set_default :conf_file, CONF_DIR + '/config'
36
+ CONF_FILE = config.system.conf_file
37
+ $:.unshift(Termtter::CONF_DIR)
38
+ end
File without changes
File without changes