termtter 1.6.0 → 1.7.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 (98) hide show
  1. data/.gitignore +5 -0
  2. data/README.rdoc +2 -2
  3. data/Rakefile +41 -75
  4. data/VERSION +1 -0
  5. data/bin/termtter +9 -2
  6. data/doc/Termtter-1.0-Release-Note-English.txt +37 -0
  7. data/doc/Termtter-1.0-Release-Note.txt +37 -0
  8. data/lib/plugins/another_prompt.rb +8 -8
  9. data/lib/plugins/ar.rb +102 -0
  10. data/lib/plugins/async.rb +1 -1
  11. data/lib/plugins/babelfish.rb +34 -0
  12. data/lib/plugins/confirm.rb +2 -0
  13. data/lib/plugins/crypt.rb +44 -0
  14. data/lib/plugins/defaults/auto_reload.rb +1 -1
  15. data/lib/plugins/defaults/command_line.rb +34 -17
  16. data/lib/plugins/defaults/confirm.rb +30 -0
  17. data/lib/plugins/defaults/hashtag.rb +1 -1
  18. data/lib/plugins/defaults/irb.rb +30 -0
  19. data/lib/plugins/defaults/keyword.rb +58 -0
  20. data/lib/plugins/defaults/list.rb +155 -0
  21. data/lib/plugins/defaults/plugin.rb +59 -0
  22. data/lib/plugins/defaults/retweet.rb +75 -23
  23. data/lib/plugins/defaults/standard_commands.rb +60 -87
  24. data/lib/plugins/defaults/standard_completion.rb +25 -15
  25. data/lib/plugins/defaults/stdout.rb +49 -10
  26. data/lib/plugins/defaults/switch.rb +1 -1
  27. data/lib/plugins/defaults/users.rb +63 -0
  28. data/lib/plugins/draft.rb +58 -0
  29. data/lib/plugins/expand-tinyurl.rb +5 -9
  30. data/lib/plugins/favotter.rb +1 -1
  31. data/lib/plugins/footer.rb +22 -0
  32. data/lib/plugins/friends.rb +5 -4
  33. data/lib/plugins/g.rb +9 -16
  34. data/lib/plugins/gem_install.rb +24 -0
  35. data/lib/plugins/gist.rb +20 -0
  36. data/lib/plugins/grass.rb +1 -1
  37. data/lib/plugins/gyazo.rb +78 -0
  38. data/lib/plugins/http_server.rb +1 -1
  39. data/lib/plugins/hugeurl.rb +6 -13
  40. data/lib/plugins/irc_gw.rb +15 -11
  41. data/lib/plugins/me.rb +1 -1
  42. data/lib/plugins/notify-send.rb +1 -1
  43. data/lib/plugins/notify-send3.rb +1 -1
  44. data/lib/plugins/open.rb +1 -1
  45. data/lib/plugins/open_url.rb +5 -1
  46. data/lib/plugins/pool.rb +1 -1
  47. data/lib/plugins/random.rb +1 -1
  48. data/lib/plugins/reply_retweet.rb +42 -0
  49. data/lib/plugins/screen-notify.rb +1 -1
  50. data/lib/plugins/sl.rb +3 -3
  51. data/lib/plugins/storage.rb +7 -10
  52. data/lib/plugins/storage/sqlite3.rb +155 -0
  53. data/lib/plugins/storage/status.rb +2 -0
  54. data/lib/plugins/stream.rb +1 -1
  55. data/lib/plugins/tinyurl.rb +3 -9
  56. data/lib/plugins/trends.rb +2 -2
  57. data/lib/plugins/truncate.rb +1 -1
  58. data/lib/plugins/w3mimg.rb +1 -1
  59. data/lib/termtter.rb +19 -20
  60. data/lib/termtter/active_rubytter.rb +4 -0
  61. data/lib/termtter/api.rb +22 -5
  62. data/lib/termtter/client.rb +55 -40
  63. data/lib/termtter/command.rb +3 -2
  64. data/lib/termtter/config_setup.rb +1 -1
  65. data/lib/termtter/config_template.erb +5 -0
  66. data/lib/termtter/default_config.rb +18 -0
  67. data/lib/termtter/hookable.rb +1 -0
  68. data/lib/termtter/httppool.rb +44 -0
  69. data/lib/termtter/memory_cache.rb +32 -0
  70. data/lib/termtter/optparse.rb +8 -15
  71. data/lib/termtter/rubytter_proxy.rb +65 -4
  72. data/lib/termtter/system_extensions.rb +40 -9
  73. data/lib/termtter/task.rb +2 -1
  74. data/spec/plugins/defaults/hashtag_spec.rb +8 -7
  75. data/spec/plugins/defaults/list_spec.rb +33 -0
  76. data/spec/plugins/defaults/plugin_spec.rb +17 -0
  77. data/spec/plugins/defaults/retweet_spec.rb +205 -0
  78. data/spec/plugins/draft_spec.rb +59 -0
  79. data/spec/plugins/expand-tinyurl_spec.rb +21 -0
  80. data/spec/plugins/footer_spec.rb +50 -0
  81. data/spec/plugins/storage/sqlite3_spec.rb +41 -0
  82. data/spec/termtter/api_spec.rb +1 -1
  83. data/spec/termtter/client_spec.rb +21 -21
  84. data/spec/termtter/command_spec.rb +8 -8
  85. data/spec/termtter/config_spec.rb +2 -2
  86. data/spec/termtter/memory_cache_spec.rb +20 -0
  87. data/spec/termtter/optparse_spec.rb +1 -1
  88. data/spec/termtter/rubytter_proxy_spec.rb +38 -0
  89. data/spec/termtter/system_extensions_spec.rb +25 -23
  90. data/spec/termtter/task_manager_spec.rb +1 -1
  91. data/spec/termtter_spec.rb +4 -2
  92. metadata +88 -19
  93. data/lib/plugins/defaults/lists.rb +0 -14
  94. data/lib/plugins/irb.rb +0 -6
  95. data/lib/plugins/storage/DB.rb +0 -37
  96. data/lib/termtter/version.rb +0 -4
  97. data/spec/plugins/defaults/lists_spec.rb +0 -34
  98. data/spec/plugins/storage/DB_spec_.rb +0 -12
@@ -1,43 +1,95 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- config.plugins.retweet.set_default(:format, '<%= comment %>RT @<%=s.user.screen_name%>: <%=s.text%>')
4
- config.plugins.retweet.set_default(:confirm_protected, true)
3
+ config.plugins.retweet.set_default(
4
+ :format, '<%= comment %><%= rt_or_qt %> @<%=s.user.screen_name%>: <%=s.text%>')
5
+ config.plugins.retweet.set_default(
6
+ :confirm_protected, true)
7
+ config.plugins.retweet.set_default(
8
+ :official_retweet, true)
9
+ config.plugins.retweet.set_default(
10
+ :quotetweet, false)
5
11
 
6
12
  module Termtter::Client
7
13
  def self.post_retweet(s, comment = nil)
8
- if s.user.protected && config.plugins.retweet.confirm_protected &&
9
- !confirm("#{s.user.screen_name} is protected! Are you sure?", false)
14
+ s.user.protected and
15
+ config.plugins.retweet.confirm_protected and
16
+ !confirm("#{s.user.screen_name} is protected! Are you sure?", false) and
10
17
  return
11
- end
12
18
 
19
+ # NOTE: If it's possible, this plugin tries to
20
+ # use the default RT feature twitter provides.
21
+ if comment.nil? && config.plugins.retweet.official_retweet
22
+ begin
23
+ Termtter::API.twitter.retweet(s.id)
24
+ # TODO: Vimshell support
25
+ puts TermColor.parse("<blue>=&gt; RT @#{s.user.screen_name}: #{s.text}</blue>")
26
+ return
27
+ rescue Rubytter::APIError # XXX: just for transition period
28
+ if $!.to_s == 'Not found'
29
+ Termtter::Client.logger.warn "Failed official retweet. Set twitter langage to English in https://twitter.com/account/settings or set config.plugins.retweet.official_retweet to false."
30
+ end
31
+ end
32
+ end
13
33
  comment += ' ' unless comment.nil?
34
+ rt_or_qt = (config.plugins.retweet.quotetweet and comment) ? 'QT' : 'RT'
14
35
  text = ERB.new(config.plugins.retweet.format).result(binding)
15
36
  Termtter::API.twitter.update(text)
16
37
  puts "=> #{text}"
17
-
18
- return text
19
38
  end
20
39
 
21
40
  register_command(
22
- :name => :retweet,
23
- :aliases => [:rt],
24
- :help => ['retweet,rt (ID|@USER)', 'Post a retweet message'],
25
- :exec_proc => lambda {|arg|
41
+ :name => :retweet,
42
+ :alias => :rt,
43
+ :help => ['retweet,rt (ID|@USER)', 'Post a retweet message'],
44
+ :exec => lambda {|arg|
26
45
  arg, comment = arg.split(/\s/, 2)
27
46
 
28
- if public_storage[:typable_id] && s = typable_id_status(arg)
29
- post_retweet(s, comment)
30
- else
31
- case arg
32
- when /(\d+)/
33
- post_retweet(Termtter::API.twitter.show(arg), comment)
34
- when /@([A-Za-z0-9_]+)/
35
- user = $1
36
- statuses = Termtter::API.twitter.user_timeline(user)
37
- return if statuses.empty?
38
- post_retweet(statuses[0], comment)
39
- end
47
+ case arg
48
+ when /(\d+)/
49
+ post_retweet(Termtter::API.twitter.show(arg), comment)
50
+ when /@([A-Za-z0-9_]+)/
51
+ user = $1
52
+ statuses = Termtter::API.twitter.user_timeline(user)
53
+ return if statuses.empty?
54
+ post_retweet(statuses[0], comment)
40
55
  end
41
56
  }
42
57
  )
58
+
59
+ register_command(
60
+ :name => :retweets,
61
+ :help => ['retweets ID', 'Show retweets of a tweet'],
62
+ :exec => lambda {|arg|
63
+ statuses = Termtter::API.twitter.retweets(arg)
64
+ output(statuses, :retweets)
65
+ }
66
+ )
67
+
68
+ register_command(
69
+ :name => :retweeted_by_me,
70
+ :help => ['retweeted_by_me', 'Show retweets posted by you.'],
71
+ :exec => lambda {|arg|
72
+ statuses = Termtter::API.twitter.retweeted_by_me
73
+ output(statuses, :retweeted_by_me)
74
+ }
75
+ )
76
+
77
+ register_command(
78
+ :name => :retweeted_to_me,
79
+ :help => ['retweeted_to_me', 'Show retweets posted by friends.'],
80
+ :exec => lambda {|arg|
81
+ statuses = Termtter::API.twitter.retweeted_to_me
82
+ output(statuses, :retweeted_to_me)
83
+ }
84
+ )
85
+
86
+ register_command(
87
+ :name => :retweets_of_me,
88
+ :help => ['retweets_of_me',
89
+ 'Show tweets of you that have been retweeted by others.'],
90
+ :exec => lambda {|arg|
91
+ statuses = Termtter::API.twitter.retweets_of_me
92
+ output(statuses, :retweets_of_me)
93
+ }
94
+ )
43
95
  end
@@ -7,7 +7,7 @@ config.plugins.standard.set_default(
7
7
  :limit_format,
8
8
  '<<%=remaining_color%>><%=limit.remaining_hits%></<%=remaining_color%>>/<%=limit.hourly_limit%> until <%=Time.parse(limit.reset_time).getlocal%> (<%=remaining_time%> remaining)')
9
9
 
10
- config.set_default(:easy_reply, true)
10
+ config.set_default(:easy_reply, false)
11
11
 
12
12
  module Termtter::Client
13
13
 
@@ -15,20 +15,21 @@ module Termtter::Client
15
15
  :name => :reload,
16
16
  :exec => lambda {|arg|
17
17
  args = @since_id ? [{:since_id => @since_id}] : []
18
- statuses = Termtter::API.twitter.friends_timeline(*args)
18
+ statuses = Termtter::API.twitter.home_timeline(*args)
19
19
  unless statuses.empty?
20
20
  print "\e[0G" + "\e[K" unless win?
21
21
  @since_id = statuses[0].id
22
22
  output(statuses, :update_friends_timeline)
23
23
  Readline.refresh_line if arg =~ /\-r/
24
24
  end
25
- }
25
+ },
26
+ :help => ['reload', 'Reload time line']
26
27
  )
27
28
 
28
29
  register_command(
29
30
  :name => :update, :alias => :u,
30
31
  :exec => lambda {|arg|
31
- unless arg.rstrip.empty?
32
+ unless arg.empty?
32
33
  params =
33
34
  if config.easy_reply && /^\s*(@\w+)/ =~ arg
34
35
  user_name = normalize_as_user_name($1)
@@ -39,7 +40,12 @@ module Termtter::Client
39
40
  end
40
41
 
41
42
  result = Termtter::API.twitter.update(arg, params)
42
- puts "updated => #{result.text}"
43
+
44
+ if result.text == arg
45
+ puts "updated => #{result.text}"
46
+ else
47
+ puts TermColor.parse("<red>Failed to update :(</red>")
48
+ end
43
49
  end
44
50
  },
45
51
  :help => ["update,u TEXT", "Post a new message"]
@@ -63,60 +69,39 @@ module Termtter::Client
63
69
  :help => ['delete,del [STATUS ID]', 'Delete a status']
64
70
  )
65
71
 
66
- direct_message_struct = Struct.new(:id, :text, :user, :created_at)
67
- direct_message_struct.class_eval do
68
- def method_missing(*args, &block)
69
- nil
72
+ unless defined? DirectMessage
73
+ class DirectMessage < Struct.new(:id, :text, :user, :created_at)
74
+ def method_missing(*args, &block)
75
+ nil
76
+ end
70
77
  end
71
78
  end
72
- register_command(
73
- :name => :direct, :aliases => [:d],
74
- :exec_proc => lambda {|arg|
75
- case arg
76
- when /^([^\s]+)\s+?(.*)\s*$/
77
- user, text = normalize_as_user_name($1), $2
78
- Termtter::API.twitter.direct_message(user, text)
79
- puts "=> to:#{user} message:#{text}"
80
- when 'list'
81
- output(
82
- Termtter::API.twitter.direct_messages.map { |d|
83
- direct_message_struct.new(d.id, "#{d.text} => #{d.recipient_screen_name}", d.sender, d.created_at)
84
- },
85
- :direct_messages
86
- )
87
- when 'sent_list'
88
- output(
89
- Termtter::API.twitter.sent_direct_messages.map { |d|
90
- direct_message_struct.new(d.id, "#{d.text} => #{d.recipient_screen_name}", d.sender, d.created_at)
91
- },
92
- :direct_messages
93
- )
94
- end
95
- },
96
- :help => [
97
- ["direct,d USERNAME TEXT", "Send direct message"],
98
- ["direct,d list", 'List direct messages'],
99
- ["direct,d sent_list", 'List sent direct messages']
100
- ]
101
- )
102
79
 
103
- register_command(
104
- :name => :profile, :aliases => [:p],
105
- :exec_proc => lambda {|arg|
106
- user_name = arg.empty? ? config.user_name : arg
107
- user = Termtter::API.twitter.user(user_name)
108
- attrs = %w[ name screen_name url description profile_image_url location protected following
109
- friends_count followers_count statuses_count favourites_count
110
- id time_zone created_at utc_offset notifications
111
- ]
112
- label_width = attrs.map(&:size).max
113
- attrs.each do |attr|
114
- value = user.__send__(attr.to_sym)
115
- puts "#{attr.gsub('_', ' ').rjust(label_width)}: #{value}"
116
- end
117
- },
118
- :help => ["profile,p [USERNAME]", "Show user's profile."]
119
- )
80
+ register_command(:direct, :alias => :d, :help => ["direct,d USERNAME TEXT", "Send direct message"]) do |arg|
81
+ if /^([^\s]+)\s+?(.*)\s*$/ =~ arg
82
+ user, text = normalize_as_user_name($1), $2
83
+ Termtter::API.twitter.direct_message(user, text)
84
+ puts "=> to:#{user} message:#{text}"
85
+ end
86
+ end
87
+
88
+ register_command('direct list', :help => ["direct,d list", 'List direct messages']) do |arg|
89
+ output(
90
+ Termtter::API.twitter.direct_messages.map { |d|
91
+ DirectMessage.new(d.id, "#{d.text} => #{d.recipient_screen_name}", d.sender, d.created_at)
92
+ },
93
+ :direct_messages
94
+ )
95
+ end
96
+
97
+ register_command('direct sent_list', :help => ["direct,d sent_list", 'List sent direct messages']) do |arg|
98
+ output(
99
+ Termtter::API.twitter.sent_direct_messages.map { |d|
100
+ DirectMessage.new(d.id, "#{d.text} => #{d.recipient_screen_name}", d.sender, d.created_at)
101
+ },
102
+ :direct_messages
103
+ )
104
+ end
120
105
 
121
106
  register_command(
122
107
  :name => :followers,
@@ -125,10 +110,12 @@ module Termtter::Client
125
110
  user_name = config.user_name if user_name.empty?
126
111
 
127
112
  followers = []
128
- page = 0
113
+ cursor = -1
129
114
  begin
130
- followers += tmp = Termtter::API.twitter.followers(user_name, :page => page+=1)
131
- end until tmp.empty?
115
+ tmp = Termtter::API.twitter.followers(user_name, :cursor => cursor)
116
+ cursor = tmp[:next_cursor]
117
+ followers += tmp[:users]
118
+ end until cursor.zero?
132
119
  Termtter::Client.public_storage[:followers] = followers
133
120
  public_storage[:users] += followers.map(&:screen_name)
134
121
  puts followers.map(&:screen_name).join(' ')
@@ -136,32 +123,6 @@ module Termtter::Client
136
123
  :help => ["followers", "Show followers"]
137
124
  )
138
125
 
139
- register_command(
140
- :name => :list, :aliases => [:l],
141
- :exec_proc => lambda {|arg|
142
- if arg =~ /\-([\d]+)/
143
- options = {:count => $1}
144
- arg = arg.gsub(/\-([\d]+)/, '')
145
- else
146
- options = {}
147
- end
148
-
149
- if arg.empty?
150
- event = :list_friends_timeline
151
- statuses = Termtter::API.twitter.friends_timeline(options)
152
- else
153
- event = :list_user_timeline
154
- statuses = []
155
- Array(arg.split).each do |user|
156
- user_name = normalize_as_user_name(user)
157
- statuses += Termtter::API.twitter.user_timeline(user_name, options)
158
- end
159
- end
160
- output(statuses, event)
161
- },
162
- :help => ["list,l [USERNAME] [-COUNT]", "List the posts"]
163
- )
164
-
165
126
  class SearchEvent; attr_reader :query; def initialize(query); @query = query end; end
166
127
  public_storage[:search_keywords] = Set.new
167
128
  register_command(
@@ -190,7 +151,14 @@ module Termtter::Client
190
151
  register_command(
191
152
  :name => :replies, :aliases => [:r],
192
153
  :exec_proc => lambda {|arg|
193
- res = Termtter::API.twitter.replies
154
+ if arg =~ /\-([\d]+)/
155
+ options = {:count => $1}
156
+ arg = arg.gsub(/\-([\d]+)/, '')
157
+ else
158
+ options = {}
159
+ end
160
+
161
+ res = Termtter::API.twitter.replies(options)
194
162
  unless arg.empty?
195
163
  res = res.map {|e| e.user.screen_name == arg ? e : nil }.compact
196
164
  end
@@ -254,6 +222,11 @@ module Termtter::Client
254
222
  :help => ['leave USER', 'Leave user']
255
223
  )
256
224
 
225
+ help = ['favorite_list USERNAME', 'show user favorites']
226
+ register_command(:favorites, :alias => :favlist, :help => help) do |arg|
227
+ output Termtter::API.twitter.favorites(arg), :user_timeline
228
+ end
229
+
257
230
  register_command(
258
231
  :name => :favorite, :aliases => [:fav],
259
232
  :exec_proc => lambda {|arg|
@@ -471,7 +444,7 @@ module Termtter::Client
471
444
  return if i <= 0
472
445
  end while input == "redo" or input == "."
473
446
  begin
474
- Termtter::Client.call_commands(input)
447
+ Termtter::Client.execute(input)
475
448
  rescue CommandNotFound => e
476
449
  warn "Unknown command \"#{e}\""
477
450
  warn 'Enter "help" for instructions'
@@ -4,20 +4,6 @@ require 'set'
4
4
 
5
5
  module Termtter::Client
6
6
 
7
- #
8
- # completion for status ids
9
- # (I want to delete)
10
- #
11
-
12
- public_storage[:status_ids] ||= Set.new
13
-
14
- register_hook(:collect_status_ids, :point => :pre_filter) do |statuses, event|
15
- statuses.each do |s|
16
- public_storage[:status_ids].add(s.id)
17
- public_storage[:status_ids].add(s.in_reply_to_status_id) if s.in_reply_to_status_id
18
- end
19
- end
20
-
21
7
  #
22
8
  # completion for user names
23
9
  #
@@ -53,9 +39,19 @@ module Termtter::Client
53
39
 
54
40
  public_storage[:hashtags_for_completion] ||= Set.new
55
41
 
42
+ def self.collect_hashtags(text)
43
+ text.force_encoding("UTF-8") if text.respond_to?(:force_encoding)
44
+ public_storage[:hashtags_for_completion] += text.scan(/#([0-9A-Za-z_]+)/u).flatten
45
+ end
46
+
47
+ Termtter::RubytterProxy.register_hook(:collect_hashtags, :point => :post_update) do |*args|
48
+ collect_hashtags(args.first)
49
+ args
50
+ end
51
+
56
52
  register_hook(:collect_hashtags, :point => :pre_filter) do |statuses, event|
57
53
  statuses.each do |s|
58
- public_storage[:hashtags_for_completion] += s.text.scan(/#([^\s]+)/).flatten
54
+ collect_hashtags(s.text)
59
55
  end
60
56
  end
61
57
 
@@ -69,4 +65,18 @@ module Termtter::Client
69
65
  map { |i| "#{command_str} ##{i}" }
70
66
  end
71
67
  end
68
+
69
+ #
70
+ # completion for lists
71
+ #
72
+
73
+ register_hook(:lists_completion, :point => :completion) do |input|
74
+ if /(.*)\s([^\s]*)$/ =~ input
75
+ command = $1
76
+ part_of_list_name = $2
77
+ public_storage[:lists].
78
+ grep(/#{Regexp.quote(part_of_list_name)}/i).
79
+ map {|u| "#{command} %s" % u }
80
+ end
81
+ end
72
82
  end
@@ -7,8 +7,16 @@ require 'tempfile'
7
7
  config.plugins.stdout.set_default(:colors, (31..36).to_a + (91..96).to_a)
8
8
  config.plugins.stdout.set_default(
9
9
  :timeline_format,
10
- '<90><%=time%> [<%=status_id%>]</90> <<%=color%>><%=s.user.screen_name%>: <%=text%></<%=color%>> ' +
11
- '<90><%=reply_to_status_id ? " (reply_to [#{reply_to_status_id}]) " : ""%><%=source%><%=s.user.protected ? "[P]" : ""%></90>'
10
+ [
11
+ '<90><%=time%> [<%=status_id%>]</90> ',
12
+ '<%= indent_text %>',
13
+ '<<%=color%>><%=s.user.screen_name%>: <%=colorize_users(text)%></<%=color%>> ',
14
+ '<90>',
15
+ '<%=reply_to_status_id ? " (reply_to [#{reply_to_status_id}]) " : ""%>',
16
+ '<%=retweeted_status_id ? " (retweet_to [#{retweeted_status_id}]) " : ""%>',
17
+ '<%=source%><%=s.user.protected ? "[P]" : ""%>',
18
+ '</90>'
19
+ ].join('')
12
20
  )
13
21
  config.plugins.stdout.set_default(:time_format_today, '%H:%M:%S')
14
22
  config.plugins.stdout.set_default(:time_format_not_today, '%y/%m/%d %H:%M')
@@ -17,7 +25,9 @@ config.plugins.stdout.set_default(:pager, 'less -R -f +G')
17
25
  config.plugins.stdout.set_default(:window_height, 50)
18
26
  config.plugins.stdout.set_default(:typable_ids, ('aa'..'zz').to_a)
19
27
  config.plugins.stdout.set_default(:typable_id_prefix, '$')
20
- config.plugins.stdout.set_default(:show_as_thread, false) # db plugin is required
28
+ config.plugins.stdout.set_default(:show_reply_chain, true)
29
+ config.plugins.stdout.set_default(:indent_format, %q("#{' ' * (indent - 1)} → "))
30
+ config.plugins.stdout.set_default(:max_indent_level, 1)
21
31
 
22
32
  module Termtter
23
33
  class TypableIdGenerator
@@ -109,10 +119,17 @@ module Termtter
109
119
  color = config.plugins.stdout.colors[s.user.id.to_i % config.plugins.stdout.colors.size]
110
120
  status_id = Termtter::Client.data_to_typable_id(s.id)
111
121
  reply_to_status_id =
112
- if s.in_reply_to_status_id.nil?
122
+ if s.in_reply_to_status_id
123
+ Termtter::Client.data_to_typable_id(s.in_reply_to_status_id)
124
+ else
113
125
  nil
126
+ end
127
+
128
+ retweeted_status_id =
129
+ if s.retweeted_status
130
+ Termtter::Client.data_to_typable_id(s.retweeted_status.id)
114
131
  else
115
- Termtter::Client.data_to_typable_id(s.in_reply_to_status_id)
132
+ nil
116
133
  end
117
134
 
118
135
  time = "(#{Time.parse(s.created_at).strftime(time_format)})"
@@ -122,18 +139,40 @@ module Termtter
122
139
  when 'web' then 'web'
123
140
  end
124
141
 
142
+ indent_text = indent > 0 ? eval(config.plugins.stdout.indent_format) : ''
125
143
  erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
126
- indent_text = indent > 0 ? "#{' ' * (indent - 1)} ┗ " : ''
127
144
 
128
145
  erbed_text = Client.get_hooks(:pre_coloring).inject(erbed_text){|result, hook| hook.call(result, event)}
129
146
 
130
- text = TermColor.parse(indent_text + erbed_text) + "\n"
131
- text = TermColor.unescape(text)
132
- if config.plugins.stdout.show_as_thread && s.in_reply_to_status_id
133
- text << status_line(Status[s.in_reply_to_status_id], time_format, event, indent + 1)
147
+ text = TermColor.unescape(TermColor.parse(erbed_text) + "\n")
148
+ if config.plugins.stdout.show_reply_chain && s.in_reply_to_status_id
149
+ indent += 1
150
+ unless indent > config.plugins.stdout.max_indent_level
151
+ begin
152
+ status = Termtter::API.twitter.show(s.in_reply_to_status_id)
153
+ text << status_line(status, time_format, event, indent)
154
+ rescue Rubytter::APIError
155
+ end
156
+ end
134
157
  end
135
158
  text
136
159
  end
160
+
161
+ def colorize_users(text)
162
+ text.gsub(/@(\w+)/) do |i|
163
+ user = Termtter::API.twitter.cached_user($1)
164
+ if user
165
+ color = user_color(user)
166
+ "<#{color}>#{i}</#{color}>"
167
+ else
168
+ i
169
+ end
170
+ end
171
+ end
172
+
173
+ def user_color(user)
174
+ config.plugins.stdout.colors[user.id.to_i % config.plugins.stdout.colors.size]
175
+ end
137
176
  end
138
177
 
139
178
  Client.register_hook(StdOut.new)