twterm 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/twterm.rb +1 -1
- data/lib/twterm/app.rb +2 -2
- data/lib/twterm/completer/abstract_completer.rb +25 -0
- data/lib/twterm/completer/default_completer.rb +21 -0
- data/lib/twterm/completer/screen_name_completer.rb +17 -0
- data/lib/twterm/completer/search_query_completer.rb +180 -0
- data/lib/twterm/completion_manager.rb +37 -0
- data/lib/twterm/key_mapper.rb +14 -2
- data/lib/twterm/key_mapper/abstract_key_mapper.rb +10 -3
- data/lib/twterm/key_mapper/status_key_mapper.rb +1 -0
- data/lib/twterm/repository/abstract_entity_repository.rb +4 -0
- data/lib/twterm/repository/status_repository.rb +7 -5
- data/lib/twterm/repository/user_repository.rb +0 -4
- data/lib/twterm/rest_client.rb +7 -9
- data/lib/twterm/scheduler.rb +1 -0
- data/lib/twterm/status.rb +16 -1
- data/lib/twterm/tab/new/search.rb +2 -2
- data/lib/twterm/tab/new/user.rb +1 -1
- data/lib/twterm/tab/statuses/base.rb +9 -1
- data/lib/twterm/tab/statuses/cacheable.rb +18 -0
- data/lib/twterm/tab/statuses/conversation.rb +66 -1
- data/lib/twterm/tab/statuses/list_timeline.rb +2 -2
- data/lib/twterm/tab/statuses/user_timeline.rb +11 -2
- data/lib/twterm/tweetbox.rb +46 -57
- data/lib/twterm/version.rb +1 -1
- data/spec/fixtures/list.json +69 -0
- data/spec/twterm/completer/search_query_completer_spec.rb +231 -0
- data/twterm.gemspec +1 -1
- metadata +15 -8
- data/lib/twterm/completion_mamanger.rb +0 -42
data/lib/twterm/version.rb
CHANGED
@@ -0,0 +1,69 @@
|
|
1
|
+
{
|
2
|
+
"created_at":"Fri Nov 04 21:22:36 +0000 2011",
|
3
|
+
"slug":"goonies",
|
4
|
+
"name":"Goonies",
|
5
|
+
"full_name":"@kurrik\/goonies",
|
6
|
+
"description":"For life",
|
7
|
+
"mode":"public",
|
8
|
+
"following":false,
|
9
|
+
"user":{
|
10
|
+
"geo_enabled":true,
|
11
|
+
"profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/342542280\/background7.png",
|
12
|
+
"profile_background_color":"8fc1ff",
|
13
|
+
"protected":false,
|
14
|
+
"default_profile":false,
|
15
|
+
"listed_count":127,
|
16
|
+
"profile_background_tile":true,
|
17
|
+
"created_at":"Thu Jul 19 15:58:07 +0000 2007",
|
18
|
+
"friends_count":291,
|
19
|
+
"name":"Arne Roomann-Kurrik",
|
20
|
+
"profile_sidebar_fill_color":"c7e0ff",
|
21
|
+
"notifications":false,
|
22
|
+
"utc_offset":-28800,
|
23
|
+
"profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/24229162\/arne001_normal.jpg",
|
24
|
+
"description":"Developer Advocate at Twitter, practitioner of dark sandwich arts. ",
|
25
|
+
"display_url":"roomanna.com",
|
26
|
+
"following":false,
|
27
|
+
"verified":false,
|
28
|
+
"favourites_count":190,
|
29
|
+
"profile_sidebar_border_color":"6baeff",
|
30
|
+
"followers_count":1705,
|
31
|
+
"profile_image_url":"http:\/\/a2.twimg.com\/profile_images\/24229162\/arne001_normal.jpg",
|
32
|
+
"default_profile_image":false,
|
33
|
+
"contributors_enabled":false,
|
34
|
+
"deactivated_bit":false,
|
35
|
+
"statuses_count":1935,
|
36
|
+
"profile_use_background_image":true,
|
37
|
+
"location":"Scan Francesco",
|
38
|
+
"id_str":"7588892",
|
39
|
+
"show_all_inline_media":false,
|
40
|
+
"profile_text_color":"000000",
|
41
|
+
"screen_name":"kurrik",
|
42
|
+
"follow_request_sent":false,
|
43
|
+
"profile_background_image_url":"http:\/\/a2.twimg.com\/profile_background_images\/342542280\/background7.png",
|
44
|
+
"url":"http:\/\/t.co\/SSiVavc4",
|
45
|
+
"expanded_url":"http:\/\/roomanna.com",
|
46
|
+
"is_translator":false,
|
47
|
+
"time_zone":"Pacific Time (US & Canada)",
|
48
|
+
"profile_link_color":"0084B4",
|
49
|
+
"id":7588892,
|
50
|
+
"entities":{
|
51
|
+
"urls":[
|
52
|
+
|
53
|
+
],
|
54
|
+
"user_mentions":[
|
55
|
+
|
56
|
+
],
|
57
|
+
"hashtags":[
|
58
|
+
|
59
|
+
]
|
60
|
+
},
|
61
|
+
"suspended":false,
|
62
|
+
"lang":"en"
|
63
|
+
},
|
64
|
+
"member_count":0,
|
65
|
+
"id_str":"58300198",
|
66
|
+
"subscriber_count":0,
|
67
|
+
"id":58300198,
|
68
|
+
"uri":"\/kurrik\/goonies"
|
69
|
+
}
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'twterm/app'
|
2
|
+
require 'twterm/completer/search_query_completer'
|
3
|
+
|
4
|
+
RSpec.describe Twterm::Completer::SearchQueryCompleter do
|
5
|
+
let(:app) { Twterm::App.new }
|
6
|
+
let(:completer) { described_class.new(app) }
|
7
|
+
|
8
|
+
describe '#complete' do
|
9
|
+
subject { completer.complete(query) }
|
10
|
+
|
11
|
+
context 'when the query is empty' do
|
12
|
+
let(:query) { '' }
|
13
|
+
|
14
|
+
it { is_expected.to contain_exactly(
|
15
|
+
'@',
|
16
|
+
'OR',
|
17
|
+
':)', ':(',
|
18
|
+
'?',
|
19
|
+
'filter:', '-filter:',
|
20
|
+
'from:', '-from:',
|
21
|
+
'lang:', '-lang:',
|
22
|
+
'list:',
|
23
|
+
'since:',
|
24
|
+
'to:', '-to:',
|
25
|
+
'until:',
|
26
|
+
'url:', '-url:'
|
27
|
+
) }
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when the query is "-"' do
|
32
|
+
let(:query) { '-' }
|
33
|
+
|
34
|
+
it { is_expected.to contain_exactly '-filter:', '-from:', '-lang:', '-to:', '-url:' }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when the query is "-f"' do
|
38
|
+
let(:query) { '-f' }
|
39
|
+
|
40
|
+
it { is_expected.to contain_exactly '-filter:', '-from:' }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when the query is "-filter:"' do
|
44
|
+
let(:query) { '-filter:' }
|
45
|
+
|
46
|
+
it { is_expected.to contain_exactly '-filter:images ', '-filter:links ', '-filter:media ', '-filter:native_video ', '-filter:periscope ', '-filter:retweets ', '-filter:safe ', '-filter:twimg ', '-filter:vine ' }
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when the query is "-lang"' do
|
50
|
+
let(:query) { '-lang' }
|
51
|
+
|
52
|
+
it { is_expected.to contain_exactly '-lang:' }
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when the query is "-lang:"' do
|
56
|
+
let(:query) { '-lang:' }
|
57
|
+
|
58
|
+
it { is_expected.not_to include '-lang:' }
|
59
|
+
it { is_expected.to include '-lang:de ' }
|
60
|
+
it { is_expected.to include '-lang:en ' }
|
61
|
+
it { is_expected.to include '-lang:fr ' }
|
62
|
+
it { is_expected.to include '-lang:ja ' }
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when the query is ":"' do
|
66
|
+
let(:query) { ':' }
|
67
|
+
|
68
|
+
it { is_expected.to contain_exactly ':) ', ':( ' }
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when the query is "?"' do
|
72
|
+
let(:query) { '?' }
|
73
|
+
|
74
|
+
it { is_expected.to contain_exactly '? ' }
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when the query is "f"' do
|
78
|
+
let(:query) { 'f' }
|
79
|
+
|
80
|
+
it { is_expected.to contain_exactly 'filter:', 'from:' }
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when the query is "filter"' do
|
84
|
+
let(:query) { 'filter' }
|
85
|
+
|
86
|
+
it { is_expected.to contain_exactly 'filter:' }
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when the query is "filter:"' do
|
90
|
+
let(:query) { 'filter:' }
|
91
|
+
|
92
|
+
it { is_expected.to contain_exactly(
|
93
|
+
'filter:images ',
|
94
|
+
'filter:links ',
|
95
|
+
'filter:media ',
|
96
|
+
'filter:native_video ',
|
97
|
+
'filter:periscope ',
|
98
|
+
'filter:retweets ',
|
99
|
+
'filter:safe ',
|
100
|
+
'filter:twimg ',
|
101
|
+
'filter:vine '
|
102
|
+
) }
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when the query is "l"' do
|
106
|
+
let(:query) { 'l' }
|
107
|
+
|
108
|
+
it { is_expected.to contain_exactly 'lang:', 'list:' }
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when the query is "lang:"' do
|
112
|
+
let(:query) { 'lang:' }
|
113
|
+
|
114
|
+
it { is_expected.not_to include 'lang:' }
|
115
|
+
it { is_expected.to include 'lang:de ' }
|
116
|
+
it { is_expected.to include 'lang:en ' }
|
117
|
+
it { is_expected.to include 'lang:fr ' }
|
118
|
+
it { is_expected.to include 'lang:ja ' }
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'when the query is "u"' do
|
122
|
+
let(:query) { 'u' }
|
123
|
+
|
124
|
+
it { is_expected.to contain_exactly 'until:', 'url:' }
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'with users' do
|
128
|
+
let(:json) { JSON.parse(fixture('user.json'), symbolize_names: true) }
|
129
|
+
|
130
|
+
before do
|
131
|
+
json[:id] = 1
|
132
|
+
json[:screen_name] = 'apple'
|
133
|
+
app.user_repository.create(Twitter::User.new(json))
|
134
|
+
|
135
|
+
json[:id] = 2
|
136
|
+
json[:screen_name] = 'banana'
|
137
|
+
app.user_repository.create(Twitter::User.new(json))
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'when the query is "@"' do
|
141
|
+
let(:query) { '@' }
|
142
|
+
|
143
|
+
it { is_expected.to include '@apple ' }
|
144
|
+
it { is_expected.to include '@banana ' }
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'when the query is "@app"' do
|
148
|
+
let(:query) { '@app' }
|
149
|
+
|
150
|
+
it { is_expected.to include '@apple ' }
|
151
|
+
it { is_expected.not_to include '@banana ' }
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'when the query is "-from:"' do
|
155
|
+
let(:query) { '-from:' }
|
156
|
+
|
157
|
+
it { is_expected.to contain_exactly '-from:apple ', '-from:banana ' }
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'when the query is "-from:app"' do
|
161
|
+
let(:query) { '-from:app' }
|
162
|
+
|
163
|
+
it { is_expected.to contain_exactly '-from:apple ' }
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'when the query is "from:"' do
|
167
|
+
let(:query) { 'from:' }
|
168
|
+
|
169
|
+
it { is_expected.to contain_exactly 'from:apple ', 'from:banana ' }
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'when the query is "from:app"' do
|
173
|
+
let(:query) { 'from:app' }
|
174
|
+
|
175
|
+
it { is_expected.to contain_exactly 'from:apple ' }
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'when the query is "-to:"' do
|
179
|
+
let(:query) { '-to:' }
|
180
|
+
|
181
|
+
it { is_expected.to contain_exactly '-to:apple ', '-to:banana ' }
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'when the query is "-to:app"' do
|
185
|
+
let(:query) { '-to:app' }
|
186
|
+
|
187
|
+
it { is_expected.to contain_exactly '-to:apple ' }
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'when the query is "to:"' do
|
191
|
+
let(:query) { 'to:' }
|
192
|
+
|
193
|
+
it { is_expected.to contain_exactly 'to:apple ', 'to:banana ' }
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'when the query is "to:app"' do
|
197
|
+
let(:query) { 'to:app' }
|
198
|
+
|
199
|
+
it { is_expected.to contain_exactly 'to:apple ' }
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context 'with lists' do
|
204
|
+
let(:json) { JSON.parse(fixture('list.json'), symbolize_names: true) }
|
205
|
+
|
206
|
+
before do
|
207
|
+
json[:id] = 1
|
208
|
+
json[:full_name] = '@central/tigers'
|
209
|
+
app.list_repository.create(Twitter::List.new(json))
|
210
|
+
|
211
|
+
json[:id] = 2
|
212
|
+
json[:full_name] = '@pacific/buffaloes'
|
213
|
+
app.list_repository.create(Twitter::List.new(json))
|
214
|
+
|
215
|
+
p app.list_repository.all
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'when the query is "list:"' do
|
219
|
+
let(:query) { 'list:' }
|
220
|
+
|
221
|
+
it { is_expected.to contain_exactly 'list:central/tigers ' , 'list:pacific/buffaloes ' }
|
222
|
+
end
|
223
|
+
|
224
|
+
context 'when the query is "list:cen"' do
|
225
|
+
let(:query) { 'list:cen' }
|
226
|
+
|
227
|
+
it { is_expected.to contain_exactly 'list:central/tigers ' }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
data/twterm.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_dependency 'oauth', '~> 0.5.1'
|
25
25
|
spec.add_dependency 'toml-rb', '~> 0.3.14'
|
26
26
|
spec.add_dependency 'twitter', '~> 6.1.0'
|
27
|
-
spec.add_dependency 'twitter-text', '
|
27
|
+
spec.add_dependency 'twitter-text', '1.14.5'
|
28
28
|
|
29
29
|
spec.add_development_dependency 'bundler', '~> 1.8'
|
30
30
|
spec.add_development_dependency 'hashie', '~> 3.5.6'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twterm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryota Kameoka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -98,16 +98,16 @@ dependencies:
|
|
98
98
|
name: twitter-text
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - '='
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 1.14.
|
103
|
+
version: 1.14.5
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - '='
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 1.14.
|
110
|
+
version: 1.14.5
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: bundler
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,7 +185,11 @@ files:
|
|
185
185
|
- lib/twterm/auth.rb
|
186
186
|
- lib/twterm/client.rb
|
187
187
|
- lib/twterm/color_manager.rb
|
188
|
-
- lib/twterm/
|
188
|
+
- lib/twterm/completer/abstract_completer.rb
|
189
|
+
- lib/twterm/completer/default_completer.rb
|
190
|
+
- lib/twterm/completer/screen_name_completer.rb
|
191
|
+
- lib/twterm/completer/search_query_completer.rb
|
192
|
+
- lib/twterm/completion_manager.rb
|
189
193
|
- lib/twterm/config.rb
|
190
194
|
- lib/twterm/direct_message.rb
|
191
195
|
- lib/twterm/direct_message_composer.rb
|
@@ -268,6 +272,7 @@ files:
|
|
268
272
|
- lib/twterm/tab/scrollable.rb
|
269
273
|
- lib/twterm/tab/searchable.rb
|
270
274
|
- lib/twterm/tab/statuses/base.rb
|
275
|
+
- lib/twterm/tab/statuses/cacheable.rb
|
271
276
|
- lib/twterm/tab/statuses/conversation.rb
|
272
277
|
- lib/twterm/tab/statuses/favorites.rb
|
273
278
|
- lib/twterm/tab/statuses/home.rb
|
@@ -287,11 +292,13 @@ files:
|
|
287
292
|
- lib/twterm/utils.rb
|
288
293
|
- lib/twterm/version.rb
|
289
294
|
- lib/twterm/view.rb
|
295
|
+
- spec/fixtures/list.json
|
290
296
|
- spec/fixtures/status.json
|
291
297
|
- spec/fixtures/user.json
|
292
298
|
- spec/resources/config
|
293
299
|
- spec/spec_helper.rb
|
294
300
|
- spec/supports/shared_examples/abstract_key_mapper.rb
|
301
|
+
- spec/twterm/completer/search_query_completer_spec.rb
|
295
302
|
- spec/twterm/config_spec.rb
|
296
303
|
- spec/twterm/event/screen/resize_spec.rb
|
297
304
|
- spec/twterm/event_dispatcher_spec.rb
|
@@ -334,7 +341,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
334
341
|
version: '0'
|
335
342
|
requirements: []
|
336
343
|
rubyforge_project:
|
337
|
-
rubygems_version: 2.6.
|
344
|
+
rubygems_version: 2.6.13
|
338
345
|
signing_key:
|
339
346
|
specification_version: 4
|
340
347
|
summary: A full-featured TUI Twitter client
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Twterm
|
2
|
-
class CompletionManager
|
3
|
-
def initialize(app)
|
4
|
-
@app = app
|
5
|
-
|
6
|
-
Readline.basic_word_break_characters = " \t\n\"\\'`$><=;|&{("
|
7
|
-
Readline.completion_case_fold = false
|
8
|
-
end
|
9
|
-
|
10
|
-
def set_default_mode!
|
11
|
-
Readline.completion_append_character = ' '
|
12
|
-
|
13
|
-
Readline.completion_proc = proc do |str|
|
14
|
-
if str.start_with?('#')
|
15
|
-
app.hashtag_repository.all
|
16
|
-
.map { |tag| "##{tag}" }
|
17
|
-
.select { |tag| tag.start_with?(str) }
|
18
|
-
elsif str.start_with?('@')
|
19
|
-
app.user_repository.all
|
20
|
-
.map { |user| "@#{user.screen_name}" }
|
21
|
-
.select { |name| name.start_with?(str) }
|
22
|
-
else
|
23
|
-
[]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def set_screen_name_mode!
|
29
|
-
Readline.completion_append_character = ''
|
30
|
-
|
31
|
-
Readline.completion_proc = proc do |str|
|
32
|
-
app.user_repository.all
|
33
|
-
.map { |user| user.screen_name }
|
34
|
-
.select { |name| name.start_with?(str) }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
attr_reader :app
|
41
|
-
end
|
42
|
-
end
|