termtter 1.3.1 → 1.4.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.
Files changed (48) hide show
  1. data/README.rdoc +1 -8
  2. data/Rakefile +13 -3
  3. data/lib/plugins/command_plus.rb +14 -14
  4. data/lib/plugins/confirm.rb +10 -4
  5. data/lib/plugins/countter.rb +18 -18
  6. data/lib/plugins/db.rb +1 -1
  7. data/lib/plugins/defaults/alias.rb +69 -0
  8. data/lib/plugins/defaults/auto_reload.rb +2 -2
  9. data/lib/plugins/defaults/command_line.rb +9 -0
  10. data/lib/plugins/defaults/fib.rb +5 -23
  11. data/lib/plugins/defaults/retweet.rb +17 -13
  12. data/lib/plugins/defaults/standard_commands.rb +40 -63
  13. data/lib/plugins/defaults/standard_completion.rb +14 -9
  14. data/lib/plugins/defaults/stdout.rb +32 -19
  15. data/lib/plugins/defaults.rb +1 -0
  16. data/lib/plugins/erb.rb +4 -8
  17. data/lib/plugins/expand-tinyurl.rb +4 -0
  18. data/lib/plugins/fibyou.rb +12 -0
  19. data/lib/plugins/group.rb +19 -20
  20. data/lib/plugins/hi.rb +15 -0
  21. data/lib/plugins/hugeurl.rb +1 -1
  22. data/lib/plugins/irc_gw.rb +53 -5
  23. data/lib/plugins/itunes.rb +33 -0
  24. data/lib/plugins/jakigan.rb +30 -0
  25. data/lib/plugins/list_with_opts.rb +1 -1
  26. data/lib/plugins/multi_output.rb +34 -0
  27. data/lib/plugins/multi_post.rb +30 -15
  28. data/lib/plugins/open.rb +44 -0
  29. data/lib/plugins/paranoid.rb +11 -0
  30. data/lib/plugins/quick_exit.rb +9 -0
  31. data/lib/plugins/replace.rb +54 -0
  32. data/lib/plugins/saykanji.rb +1 -1
  33. data/lib/plugins/searchline.rb +44 -0
  34. data/lib/plugins/tinyurl.rb +7 -1
  35. data/lib/plugins/train.rb +24 -0
  36. data/lib/termtter/active_rubytter.rb +39 -0
  37. data/lib/termtter/api.rb +24 -21
  38. data/lib/termtter/client.rb +17 -29
  39. data/lib/termtter/config_setup.rb +27 -2
  40. data/lib/termtter/config_template.erb +2 -2
  41. data/lib/termtter/version.rb +1 -1
  42. data/lib/termtter.rb +9 -4
  43. data/spec/plugins/db_spec.rb +1 -1
  44. data/spec/plugins/fib_spec.rb +1 -1
  45. data/spec/plugins/standard_commands_spec.rb +4 -0
  46. data/spec/plugins/whois_spec.rb +7 -7
  47. data/spec/termtter/active_rubytter_spec.rb +70 -0
  48. metadata +29 -5
data/README.rdoc CHANGED
@@ -37,6 +37,7 @@ Search
37
37
  * json_pure or json
38
38
  * termcolor
39
39
  * rubytter
40
+ * highline
40
41
 
41
42
  == INSTALL:
42
43
 
@@ -44,14 +45,6 @@ Search
44
45
 
45
46
  == CONFIGURATION:
46
47
 
47
- Termtter generates a configuration file named '~/.termtter/config'.
48
- You can edit the file anytime.
49
-
50
- % vim ~/.termtter/config
51
-
52
- config.user_name = 'USERNAME'
53
- config.password = 'PASSWORD'
54
-
55
48
  If you would like to use proxy server, add configurations like this:
56
49
 
57
50
  config.proxy.host = 'PROXYHOST'
data/Rakefile CHANGED
@@ -21,11 +21,12 @@ spec = Gem::Specification.new do |s|
21
21
  s.executables = ["kill_termtter", "termtter"]
22
22
  s.add_dependency("json_pure", ">= 1.1.3")
23
23
  s.add_dependency("highline", ">= 1.5.0")
24
- s.add_dependency("termcolor", ">= 0.3.1")
25
- s.add_dependency("rubytter", ">= 0.6.4")
24
+ s.add_dependency("termcolor", ">= 1.0.0")
25
+ s.add_dependency("rubytter", ">= 0.9.2")
26
+ s.add_dependency("oauth", ">= 0.3.6")
26
27
  s.authors = %w(jugyo ujihisa)
27
28
  s.email = 'jugyo.org@gmail.com'
28
- s.homepage = 'http://wiki.github.com/jugyo/termtter'
29
+ s.homepage = 'http://termtter.org/'
29
30
  s.rubyforge_project = 'termtter'
30
31
  s.has_rdoc = true
31
32
  s.rdoc_options = ["--main", "README.rdoc", "--exclude", "spec"]
@@ -62,6 +63,14 @@ Spec::Rake::SpecTask.new do |t|
62
63
  t.spec_files = FileList['spec/**/*_spec.rb']
63
64
  t.spec_opts = ['-c']
64
65
  end
66
+ desc "Run all examples with RCov"
67
+
68
+ Spec::Rake::SpecTask.new('rcov') do |t|
69
+ t.spec_files = FileList['spec/**/*_spec.rb']
70
+ t.spec_opts = ['-c', '-fs']
71
+ t.rcov = true
72
+ t.rcov_opts = ['-x', 'spec', '--exclude', 'lib/plugins']
73
+ end
65
74
 
66
75
  Rake::RDocTask.new do |t|
67
76
  t.rdoc_dir = 'rdoc'
@@ -72,3 +81,4 @@ Rake::RDocTask.new do |t|
72
81
  end
73
82
 
74
83
  CLEAN.include [ 'pkg', 'rdoc' ]
84
+
@@ -26,22 +26,22 @@ end
26
26
 
27
27
  module Termtter::Client
28
28
  register_command(
29
- :name => :delete_command,
30
- :exec_proc => lambda {|arg|
31
- Termtter::Client.delete_command(arg)
32
- },
33
- :completion_proc => lambda {|cmd, arg|
34
- },
35
- :help => ['delete_command command', 'delete command from command list (this command is experimental!)']
29
+ :name => :delete_command,
30
+ :exec_proc => lambda {|arg|
31
+ Termtter::Client.delete_command(arg)
32
+ },
33
+ :completion_proc => lambda {|cmd, arg|
34
+ },
35
+ :help => ['delete_command command', 'delete command from command list (this command is experimental!)']
36
36
  )
37
37
 
38
38
  register_command(
39
- :name => :alias_command,
40
- :exec_proc => lambda {|arg|
41
- Termtter::Client.alias_command(arg)
42
- },
43
- :completion_proc => lambda {|cmd, arg|
44
- },
45
- :help => ['alias_command A B', 'alias command A to B (this command is experimental!)']
39
+ :name => :alias_command,
40
+ :exec_proc => lambda {|arg|
41
+ Termtter::Client.alias_command(arg)
42
+ },
43
+ :completion_proc => lambda {|cmd, arg|
44
+ },
45
+ :help => ['alias_command A B', 'alias command A to B (this command is experimental!)']
46
46
  )
47
47
  end
@@ -4,7 +4,7 @@ config.plugins.confirm.set_default(:commands, [:update, :reply, :direct])
4
4
  config.plugins.confirm.set_default(
5
5
  :conditions,
6
6
  [
7
- lambda { |cmd_name, arg|
7
+ lambda {|cmd_name, arg|
8
8
  if cmd_name == :direct && arg =~ /^(list|sent_list)$/
9
9
  false
10
10
  else
@@ -18,16 +18,22 @@ Termtter::Client.register_hook(
18
18
  :name => :confirm,
19
19
  :points => [/^pre_exec_/],
20
20
  :exec_proc => lambda {|cmd, arg|
21
- if config.plugins.confirm.commands.include?(cmd.name) &&
21
+ if config.plugins.confirm.commands.include?(cmd.name) &&
22
22
  config.plugins.confirm.conditions.any? { |cond| cond.call(cmd.name, arg) }
23
23
 
24
- prompt = "\"#{cmd.name} #{arg}".strip + "\" [Y/n] "
24
+ if arg.match(/^(\d+)\s+(.+)$/) and
25
+ (s = Termtter::API.twitter.show($1) rescue nil)
26
+ tmp_arg = "@#{s.user.screen_name} #{$2}"
27
+ else
28
+ tmp_arg = arg
29
+ end
30
+
31
+ prompt = "\"#{cmd.name} #{tmp_arg}".strip + "\" [Y/n] "
25
32
 
26
33
  if /^y?$/i !~ Readline.readline(prompt, false)
27
34
  puts 'canceled.'
28
35
  raise Termtter::CommandCanceled
29
36
  end
30
-
31
37
  end
32
38
  }
33
39
  )
@@ -1,23 +1,23 @@
1
1
  module Termtter::Client
2
2
  register_command(
3
- :name => :countter,
4
- :exec_proc => lambda {|arg|
5
- count = {}
6
- public_storage[:log].each do |l|
7
- source = l.source =~ /(?:<a href=\".+?\">)(.+)(?:<\/a>)/ ? $1 : l.source
8
- count[source] = 0 unless count[source]
9
- count[source] += 1
10
- end
3
+ :name => :countter,
4
+ :exec_proc => lambda {|arg|
5
+ count = {}
6
+ public_storage[:log].each do |l|
7
+ source = l.source =~ /(?:<a href=\".+?\">)(.+)(?:<\/a>)/ ? $1 : l.source
8
+ count[source] = 0 unless count[source]
9
+ count[source] += 1
10
+ end
11
11
 
12
- format = "%24s %6s"
13
- puts format % %w(sources count)
14
- puts format % ['-'*24, '-'*6]
15
- count.to_a.sort{|a,b|b[1]<=>a[1]}.each do |k,v|
16
- puts format % [k, v]
17
- end
18
- },
19
- :completion_proc => lambda {|cmd, arg|
20
- },
21
- :help => ['countter', 'count sources']
12
+ format = "%24s %6s"
13
+ puts format % %w(sources count)
14
+ puts format % ['-'*24, '-'*6]
15
+ count.to_a.sort{|a,b|b[1]<=>a[1]}.each do |k,v|
16
+ puts format % [k, v]
17
+ end
18
+ },
19
+ :completion_proc => lambda {|cmd, arg|
20
+ },
21
+ :help => ['countter', 'count sources']
22
22
  )
23
23
  end
data/lib/plugins/db.rb CHANGED
@@ -58,7 +58,7 @@ module Termtter
58
58
  user = {}
59
59
  User.columns.each do |col|
60
60
  user[col] =
61
- if event == :search && col == :protected
61
+ if event.class == SearchEvent && col == :protected
62
62
  false
63
63
  else
64
64
  s.user[col]
@@ -0,0 +1,69 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Examples:
4
+ #
5
+ # ~/termtter/config
6
+ #
7
+ # config.plugins.alias.aliases = {:ls => 'list', :hoge => 'update hoge'}
8
+ #
9
+ # command line
10
+ #
11
+ # > alias ls list
12
+ # > alias me list @jugyo
13
+ # > alias st search termtter
14
+ #
15
+ # > remove_alias ls
16
+ #
17
+
18
+ config.plugins.alias.set_default(:aliases, {})
19
+
20
+ module Termtter::Client
21
+ @aliases = config.plugins.alias.aliases
22
+
23
+ class << self
24
+ def register_alias(alias_name, command)
25
+ @aliases[alias_name.to_sym] = command.to_s
26
+ end
27
+ alias_method :alias, :register_alias
28
+
29
+ def remove_alias(alias_name)
30
+ @aliases.delete alias_name.to_sym
31
+ end
32
+ end
33
+
34
+ register_command(:alias,
35
+ :help => ['alias NAME COMMAND', 'Add alias for any operations']) do |text|
36
+ unless text.empty?
37
+ alias_name, command = text.split(/\s+/, 2)
38
+ next unless command
39
+ register_alias alias_name, command
40
+ puts "#{alias_name} => #{command}"
41
+ else
42
+ @aliases.keys.map{|i|i.to_s}.sort.each do |k|
43
+ puts "#{k} => #{@aliases[k.to_sym]}"
44
+ end
45
+ end
46
+ end
47
+
48
+ register_command(:remove_alias,
49
+ :help => ['remove_alias NAME', 'Remove alias completely']) do |target|
50
+ remove_alias target
51
+ end
52
+
53
+ register_hook :aliases, :point => :pre_command do |text|
54
+ unless text =~ /^\s*$/
55
+ command = text.scan(/\s*([^\s]*)\s*/).flatten.first
56
+ if original = @aliases[command.to_sym]
57
+ text = text.sub(command, original)
58
+ end
59
+ end
60
+ text
61
+ end
62
+
63
+ register_hook(:aliases_completion, :point => :completion) do |input|
64
+ if /^\s*([^\s]*)$/ =~ input
65
+ command_str = $1
66
+ @aliases.keys.map{|i|i.to_s}.grep(/^#{Regexp.quote(command_str)}/i)
67
+ end
68
+ end
69
+ end
@@ -2,7 +2,7 @@
2
2
  module Termtter::Client
3
3
  add_task(:name => :auto_reload, :interval => config.update_interval, :after => config.update_interval) do
4
4
  begin
5
- call_commands('reload')
5
+ call_commands('reload -r')
6
6
  rescue Exception => e
7
7
  handle_error(e)
8
8
  end
@@ -13,7 +13,7 @@ module Termtter::Client
13
13
  :point => :initialize,
14
14
  :exec => lambda {
15
15
  begin
16
- call_commands('reload')
16
+ call_commands('reload -r')
17
17
  rescue Exception => e
18
18
  handle_error(e)
19
19
  end
@@ -64,6 +64,7 @@ module Termtter
64
64
  if Readline.respond_to?(:basic_word_break_characters=)
65
65
  Readline.basic_word_break_characters= "\t\n\"\\'`><=;|&{("
66
66
  end
67
+ Readline.completion_case_fold = true
67
68
  Readline.completion_proc = lambda {|input|
68
69
  begin
69
70
  words = []
@@ -108,4 +109,12 @@ module Termtter
108
109
  Client.register_hook(:finalize_command_line, :point => :exit) do
109
110
  CommandLine.stop
110
111
  end
112
+
113
+ Client.register_command(:vi_editing_mode) do |arg|
114
+ Readline.vi_editing_mode
115
+ end
116
+
117
+ Client.register_command(:emacs_editing_mode) do |arg|
118
+ Readline.emacs_editing_mode
119
+ end
111
120
  end
@@ -1,25 +1,7 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  def fib(n)i=0;j=1;n.times{j=i+i=j};i end
4
- module Termtter::Client
5
- register_command(
6
- :name => :fib,
7
- :exec_proc => lambda {|arg|
8
- n = arg.to_i
9
- text = "fib(#{n}) = #{fib n}"
10
- Termtter::API.twitter.update(text)
11
- puts "=> " << text
12
- }
13
- )
14
- register_command(
15
- :name => :fibyou,
16
- :exec_proc => lambda {|arg|
17
- /(\w+)\s(\d+)/ =~ arg
18
- name = normalize_as_user_name($1)
19
- n = $2.to_i
20
- text = "@#{name} fib(#{n}) = #{fib n}"
21
- Termtter::API.twitter.update(text)
22
- puts "=> " << text
23
- }
24
- )
2
+ Termtter::Client.register_command(:fib) do |arg|
3
+ n = arg.to_i
4
+ text = "fib(#{n}) = #{fib n}"
5
+ Termtter::API.twitter.update(text)
6
+ puts "=> " << text
25
7
  end
@@ -13,6 +13,8 @@ module Termtter::Client
13
13
  text = ERB.new(config.plugins.retweet.format).result(binding)
14
14
  Termtter::API.twitter.update(text)
15
15
  puts "=> #{text}"
16
+
17
+ return text
16
18
  end
17
19
 
18
20
  register_command(
@@ -21,19 +23,21 @@ module Termtter::Client
21
23
  :help => ['retweet,rt (ID|@USER)', 'Post a retweet message'],
22
24
  :exec_proc => lambda {|arg|
23
25
  arg, comment = arg.split(/\s/, 2)
24
- if public_storage[:typable_id] && s = typable_id_status(arg)
25
- post_retweet(s, comment)
26
- else
27
- case arg
28
- when /(\d+)/
29
- post_retweet(Termtter::API.twitter.show(arg), comment)
30
- when /@([A-Za-z0-9_]+)/
31
- user = $1
32
- statuses = Termtter::API.twitter.user_timeline(user)
33
- return if statuses.empty?
34
- post_retweet(statuses[0], comment)
35
- end
36
- end
26
+ txt = if public_storage[:typable_id] && s = typable_id_status(arg)
27
+ post_retweet(s, comment)
28
+ else
29
+ case arg
30
+ when /(\d+)/
31
+ post_retweet(Termtter::API.twitter.show(arg), comment)
32
+ when /@([A-Za-z0-9_]+)/
33
+ user = $1
34
+ statuses = Termtter::API.twitter.user_timeline(user)
35
+ return if statuses.empty?
36
+ post_retweet(statuses[0], comment)
37
+ end
38
+ end
39
+
40
+ return txt
37
41
  }
38
42
  )
39
43
  end
@@ -5,7 +5,7 @@ require 'set'
5
5
 
6
6
  config.plugins.standard.set_default(
7
7
  :limit_format,
8
- '<<%=remaining_color%>><%=limit.remaining_hits%></<%=remaining_color%>>/<%=limit.hourly_limit%> until <%=limit.reset_time%> (<%=remaining_time%> remaining)')
8
+ '<<%=remaining_color%>><%=limit.remaining_hits%></<%=remaining_color%>>/<%=limit.hourly_limit%> until <%=Time.parse(limit.reset_time).getlocal%> (<%=remaining_time%> remaining)')
9
9
 
10
10
  config.set_default(:easy_reply, true)
11
11
 
@@ -17,10 +17,10 @@ module Termtter::Client
17
17
  args = @since_id ? [{:since_id => @since_id}] : []
18
18
  statuses = Termtter::API.twitter.friends_timeline(*args)
19
19
  unless statuses.empty?
20
- print "\e[1K\e[0G" unless win?
20
+ print "\e[0G" + "\e[K" unless win?
21
21
  @since_id = statuses[0].id
22
22
  output(statuses, :update_friends_timeline)
23
- Readline.refresh_line
23
+ Readline.refresh_line if arg =~ /\-r/
24
24
  end
25
25
  }
26
26
  )
@@ -103,7 +103,8 @@ module Termtter::Client
103
103
  register_command(
104
104
  :name => :profile, :aliases => [:p],
105
105
  :exec_proc => lambda {|arg|
106
- user = Termtter::API.twitter.user(normalize_as_user_name(arg))
106
+ user_name = arg.empty? ? config.user_name : arg
107
+ user = Termtter::API.twitter.user(user_name)
107
108
  attrs = %w[ name screen_name url description profile_image_url location protected following
108
109
  friends_count followers_count statuses_count favourites_count
109
110
  id time_zone created_at utc_offset notifications
@@ -114,7 +115,7 @@ module Termtter::Client
114
115
  puts "#{attr.gsub('_', ' ').rjust(label_width)}: #{value}"
115
116
  end
116
117
  },
117
- :help => ["profile,p USERNAME", "Show user's profile"]
118
+ :help => ["profile,p [USERNAME]", "Show user's profile."]
118
119
  )
119
120
 
120
121
  register_command(
@@ -154,19 +155,29 @@ module Termtter::Client
154
155
  :help => ["list,l [USERNAME]", "List the posts"]
155
156
  )
156
157
 
158
+ class SearchEvent; attr_reader :query; def initialize(query); @query = query end; end
157
159
  public_storage[:search_keywords] = Set.new
158
160
  register_command(
159
161
  :name => :search, :aliases => [:s],
160
162
  :exec_proc => lambda {|arg|
161
163
  statuses = Termtter::API.twitter.search(arg)
162
164
  public_storage[:search_keywords] << arg
163
- output(statuses, :search)
165
+ output(statuses, SearchEvent.new(arg))
164
166
  },
165
167
  :completion_proc => lambda {|cmd, arg|
166
168
  public_storage[:search_keywords].grep(/^#{Regexp.quote(arg)}/).map { |i| "#{cmd} #{i}" }
167
169
  },
168
170
  :help => ["search,s TEXT", "Search for Twitter"]
169
171
  )
172
+ register_hook(:highlight_for_search_query, :point => :pre_coloring) do |text, event|
173
+ case event
174
+ when SearchEvent
175
+ query = event.query.split(/\s/).map {|q|Regexp.quote(q)}.join("|")
176
+ text.gsub(/(#{query})/i, '<on_magenta><white>\1</white></on_magenta>')
177
+ else
178
+ text
179
+ end
180
+ end
170
181
 
171
182
  register_command(
172
183
  :name => :replies, :aliases => [:r],
@@ -189,7 +200,7 @@ module Termtter::Client
189
200
  :completion_proc => lambda {|cmd, arg|
190
201
  case arg
191
202
  when /(\w+):\s*(\d+)\s*$/
192
- find_status_ids($2).map{|id| "#{cmd} #{$1}: #{id}"}
203
+ find_status_ids($2).map {|id| "#{cmd} #{$1}: #{id}"}
193
204
  else
194
205
  users = find_users(arg)
195
206
  unless users.empty?
@@ -264,7 +275,7 @@ module Termtter::Client
264
275
  :completion_proc => lambda {|cmd, arg|
265
276
  case arg
266
277
  when /(\d+)/
267
- find_status_ids(arg).map{|id| "#{cmd} #{id}"}
278
+ find_status_ids(arg).map {|id| "#{cmd} #{id}"}
268
279
  else
269
280
  if data = Termtter::Client.typable_id_to_data(arg)
270
281
  "#{cmd} #{data}"
@@ -369,7 +380,7 @@ module Termtter::Client
369
380
  :alias => :plugin,
370
381
  :exec_proc => lambda {|arg|
371
382
  if arg.empty?
372
- puts 'Should specify plugin name.'
383
+ plugin_list
373
384
  return
374
385
  end
375
386
  begin
@@ -380,44 +391,39 @@ module Termtter::Client
380
391
  end
381
392
  },
382
393
  :completion_proc => lambda {|cmd, args|
383
- plugin_list.grep(/^#{Regexp.quote(args)}/).map{|i| "#{cmd} #{i}"}
394
+ plugin_list.grep(/^#{Regexp.quote(args)}/).map {|i| "#{cmd} #{i}"}
384
395
  },
385
396
  :help => ['plug FILE', 'Load a plugin']
386
397
  )
387
398
 
399
+ ## plugin_list :: IO ()
388
400
  def self.plugin_list
389
- (Dir["#{File.dirname(__FILE__)}/../*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]).
390
- map{|f| File.basename(f).sub(/\.rb$/, '')}.
401
+ plugin_list = (Dir["#{File.dirname(__FILE__)}/../*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]).
402
+ map {|f| File.basename(f).sub(/\.rb$/, '')}.
391
403
  sort
404
+ list = plugin_list
405
+ width = list.map {|i|i.size}.max + 2
406
+ a = []
407
+ list.sort.each_slice(4) {|i|
408
+ a << i.map {|j| j + (" " * (width - j.size))}.join
409
+ }
410
+ puts TermColor.parse('<green>' + TermColor.escape(a.join("\n")) + '</green>')
392
411
  end
393
412
 
394
- register_command(
395
- :name => :plugins,
396
- :exec_proc => lambda {|arg|
397
- list = plugin_list
398
- width = list.map{|i|i.size}.max + 2
399
- a = []
400
- list.sort.each_slice(4) {|i|
401
- a << i.map{|j| j + (" " * (width - j.size))}.join
402
- }
403
- puts TermColor.parse('<green>' + TermColor.escape(a.join("\n")) + '</green>')
404
- },
405
- :help => ['plugins', 'Show list of plugins']
406
- )
407
-
408
413
  register_command(
409
414
  :name => :reply,
410
415
  :aliases => [:re],
411
416
  :exec_proc => lambda {|arg|
412
417
  case arg
413
418
  when /^\s*(?:list|ls)\s*(?:\s+(\w+))?\s*$/
414
- public_storage[:log4re] = if $1
415
- public_storage[:log].
416
- select{|l| l.user.screen_name == $1}.
417
- sort {|a,b| a.id <=> b.id}
418
- else
419
- public_storage[:log].sort {|a,b| a.id <=> b.id}
420
- end
419
+ public_storage[:log4re] =
420
+ if $1
421
+ public_storage[:log].
422
+ select {|l| l.user.screen_name == $1}.
423
+ sort {|a,b| a.id <=> b.id}
424
+ else
425
+ public_storage[:log].sort {|a,b| a.id <=> b.id}
426
+ end
421
427
  public_storage[:log4re].each_with_index do |s, i|
422
428
  puts "#{i}: #{s.user.screen_name}: #{s.text}"
423
429
  end
@@ -445,7 +451,7 @@ module Termtter::Client
445
451
  :completion_proc => lambda {|cmd, arg|
446
452
  case arg
447
453
  when /(\d+)/
448
- find_status_ids(arg).map{|id| "#{cmd} #{id}"}
454
+ find_status_ids(arg).map {|id| "#{cmd} #{id}"}
449
455
  end
450
456
  },
451
457
  :help => ["reply,re @USERNAME or STATUS_ID", "Send a reply"]
@@ -475,35 +481,6 @@ module Termtter::Client
475
481
  :help => ["redo,.", "Execute previous command"]
476
482
  )
477
483
 
478
- register_command(:alias,
479
- :help => ['alias NAME VALUE', 'Add alias for any operations']) do |text|
480
- from, to = text.split(' ', 2)
481
- next unless to
482
- begin
483
- add_alias from, to
484
- rescue
485
- STDOUT.print 'override? [y/n] '
486
- STDOUT.flush
487
- next unless /y/ =~ STDIN.gets.chomp
488
- add_alias from, to, false
489
- end
490
- puts "#{from} => #{to}"
491
- end
492
-
493
- register_command(:remove_alias,
494
- :help => ['remove_alias NAME', 'Remove alias completely']) do |target|
495
- remove_alias target
496
- STDOUT.puts 'done'
497
- end
498
-
499
- register_hook :aliases, :point => :pre_command do |text|
500
- command, args = text.split(' ', 2)
501
- if original = @aliases[command]
502
- text = [original, args].compact.join(' ')
503
- end
504
- text
505
- end
506
-
507
484
  def self.update_with_user_and_id(text, username, id)
508
485
  text = "@#{username} #{text}"
509
486
  result = Termtter::API.twitter.update(text, {'in_reply_to_status_id' => id})
@@ -32,9 +32,9 @@ module Termtter::Client
32
32
  end
33
33
 
34
34
  register_hook(:user_names_completion, :point => :completion) do |input|
35
- if /(.*)@([^\s]*)$/ =~ input
35
+ if /(.*)\s([^\s]*)$/ =~ input
36
36
  command_str = $1
37
- part_of_user_name = $2
37
+ part_of_user_name = $2.gsub(/^@/, '')
38
38
 
39
39
  users =
40
40
  if part_of_user_name.nil? || part_of_user_name.empty?
@@ -43,7 +43,7 @@ module Termtter::Client
43
43
  public_storage[:users].grep(/^#{Regexp.quote(part_of_user_name)}/i)
44
44
  end
45
45
 
46
- users.map {|u| "#{command_str}@%s" % u }
46
+ users.map {|u| "#{command_str} @%s" % u }
47
47
  end
48
48
  end
49
49
 
@@ -51,17 +51,22 @@ module Termtter::Client
51
51
  # completion for hashtags
52
52
  #
53
53
 
54
- public_storage[:hashtag] ||= Set.new
54
+ public_storage[:hashtags] ||= Set.new
55
55
 
56
- register_hook(:collect_hashtags, :point => /^post_exec_/) do |cmd, arg, result|
57
- public_storage[:hashtag] += arg.scan(/\s+#([^\s]+)/i).flatten if arg
56
+ register_hook(:collect_hashtags, :point => :pre_filter) do |statuses, event|
57
+ statuses.each do |s|
58
+ public_storage[:hashtags] += s.text.scan(/#([^\s]+)/).flatten
59
+ end
58
60
  end
59
61
 
60
- register_hook(:hashtags_completion, :point => :completion) do |input|
61
- if /(.*)#([^\s]*)$/ =~ input
62
+ register_hook(:hashtagss_completion, :point => :completion) do |input|
63
+ if /(.*)\s#([^\s]*)$/ =~ input
62
64
  command_str = $1
63
65
  part_of_hashtag = $2
64
- public_storage[:hashtag].grep(/^#{Regexp.quote(part_of_hashtag)}/i).map { |i| "#{command_str}##{i}" }
66
+ ht = public_storage[:hashtags]
67
+ (ht.grep(/^#{Regexp.quote(part_of_hashtag)}/) | # prior
68
+ ht.grep(/^#{Regexp.quote(part_of_hashtag)}/i) ).
69
+ map { |i| "#{command_str} ##{i}" }
65
70
  end
66
71
  end
67
72
  end