twterm 1.0.10 → 1.0.11
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.
- checksums.yaml +4 -4
- data/lib/twterm.rb +3 -2
- data/lib/twterm/client.rb +6 -0
- data/lib/twterm/extensions/enumerator/lazy.rb +12 -0
- data/lib/twterm/tab/conversation_tab.rb +1 -1
- data/lib/twterm/tab/key_assignments_cheatsheet.rb +32 -39
- data/lib/twterm/tab/list_tab.rb +1 -1
- data/lib/twterm/tab/mentions_tab.rb +1 -1
- data/lib/twterm/tab/new/list.rb +21 -23
- data/lib/twterm/tab/new/search.rb +83 -5
- data/lib/twterm/tab/new/start.rb +0 -5
- data/lib/twterm/tab/scrollable.rb +138 -0
- data/lib/twterm/tab/search_tab.rb +1 -1
- data/lib/twterm/tab/statuses_tab.rb +45 -72
- data/lib/twterm/tab/timeline_tab.rb +1 -1
- data/lib/twterm/tab/user_tab.rb +1 -1
- data/lib/twterm/version.rb +1 -1
- metadata +4 -3
- data/lib/twterm/tab/scroll_manager.rb +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2572d3668fe0048eb79fa55c0b881a39fe130c7a
|
4
|
+
data.tar.gz: 8fc15104af2e69ee71861a1e903a056f3dda1f57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7f0770b2c858fee53746e64ee194218b565ff16d88d06fd336b5c3ad304716df9dc57e5a8fbd1f8eba5b377ba9ada1d97aaf580f9d68355090924de4a595451
|
7
|
+
data.tar.gz: 7ed7a151ce86516110461ea3426e742f271713d6b87038d5c331c78d4f06ed8995ed39b98d96257a2aab5d1eaff99e54ff3a106ff76699002df426ac8594519a
|
data/lib/twterm.rb
CHANGED
@@ -20,6 +20,7 @@ require 'twterm/color_manager'
|
|
20
20
|
require 'twterm/completion_mamanger'
|
21
21
|
require 'twterm/config'
|
22
22
|
require 'twterm/extensions/curses/window'
|
23
|
+
require 'twterm/extensions/enumerator/lazy'
|
23
24
|
require 'twterm/extensions/integer'
|
24
25
|
require 'twterm/extensions/string'
|
25
26
|
require 'twterm/history/base'
|
@@ -37,7 +38,7 @@ require 'twterm/tab_manager'
|
|
37
38
|
require 'twterm/tab/base'
|
38
39
|
require 'twterm/tab/dumpable'
|
39
40
|
require 'twterm/tab/exceptions'
|
40
|
-
require 'twterm/tab/
|
41
|
+
require 'twterm/tab/scrollable'
|
41
42
|
require 'twterm/tab/statuses_tab'
|
42
43
|
require 'twterm/tab/conversation_tab'
|
43
44
|
require 'twterm/tab/key_assignments_cheatsheet'
|
@@ -57,6 +58,6 @@ require 'twterm/version'
|
|
57
58
|
|
58
59
|
module Twterm
|
59
60
|
class Conf
|
60
|
-
REQUIRE_VERSION = '1.0.
|
61
|
+
REQUIRE_VERSION = '1.0.11'
|
61
62
|
end
|
62
63
|
end
|
data/lib/twterm/client.rb
CHANGED
@@ -2,6 +2,7 @@ module Twterm
|
|
2
2
|
module Tab
|
3
3
|
class KeyAssignmentsCheatsheet
|
4
4
|
include Base
|
5
|
+
include Scrollable
|
5
6
|
|
6
7
|
def ==(other)
|
7
8
|
other.is_a?(self.class)
|
@@ -38,20 +39,29 @@ module Twterm
|
|
38
39
|
}
|
39
40
|
}
|
40
41
|
|
42
|
+
def drawable_item_count
|
43
|
+
window.maxy - 3
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
super
|
48
|
+
scroller.set_cursor_free!
|
49
|
+
end
|
50
|
+
|
41
51
|
def respond_to_key(key)
|
42
52
|
case key
|
43
53
|
when ?d, 4
|
44
|
-
10.times {
|
54
|
+
10.times { scroller.move_down }
|
45
55
|
when ?g
|
46
|
-
|
56
|
+
scroller.move_to_top
|
47
57
|
when ?G
|
48
|
-
|
58
|
+
scroller.move_to_bottom
|
49
59
|
when ?j, 14, Curses::Key::DOWN
|
50
|
-
|
60
|
+
scroller.move_down
|
51
61
|
when ?k, 16, Curses::Key::UP
|
52
|
-
|
62
|
+
scroller.move_up
|
53
63
|
when ?u, 21
|
54
|
-
10.times {
|
64
|
+
10.times { scroller.move_up }
|
55
65
|
else
|
56
66
|
return false
|
57
67
|
end
|
@@ -63,51 +73,34 @@ module Twterm
|
|
63
73
|
'Key assignments'.freeze
|
64
74
|
end
|
65
75
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
76
|
+
def total_item_count
|
77
|
+
@count ||= SHORTCUTS.count * 4 + SHORTCUTS.values.map(&:count).reduce(0, :+) + 1
|
78
|
+
end
|
69
79
|
|
70
|
-
|
80
|
+
def update
|
81
|
+
offset = scroller.offset
|
82
|
+
line = 0
|
71
83
|
|
72
|
-
window.setpos(
|
73
|
-
window.bold { window.addstr('Key assignments') } if
|
84
|
+
window.setpos(line - offset + 2, 3)
|
85
|
+
window.bold { window.addstr('Key assignments') } if scroller.nth_item_drawable?(line)
|
74
86
|
|
75
87
|
SHORTCUTS.each do |category, shortcuts|
|
76
|
-
|
77
|
-
window.setpos(
|
78
|
-
window.bold { window.addstr("<#{category}>") } if
|
79
|
-
|
88
|
+
line += 3
|
89
|
+
window.setpos(line - offset + 2, 5)
|
90
|
+
window.bold { window.addstr("<#{category}>") } if scroller.nth_item_drawable?(line)
|
91
|
+
line += 1
|
80
92
|
|
81
93
|
shortcuts.each do |key, description|
|
82
|
-
|
83
|
-
next unless
|
94
|
+
line += 1
|
95
|
+
next unless scroller.nth_item_drawable?(line)
|
84
96
|
|
85
|
-
window.setpos(
|
97
|
+
window.setpos(line - offset + 2, 7)
|
86
98
|
window.bold { window.addstr(key.rjust(17)) }
|
87
|
-
window.setpos(
|
99
|
+
window.setpos(line - offset + 2, 25)
|
88
100
|
window.addstr(": #{description}")
|
89
101
|
end
|
90
102
|
end
|
91
103
|
end
|
92
|
-
|
93
|
-
private
|
94
|
-
|
95
|
-
def count
|
96
|
-
@count ||= SHORTCUTS.count * 4 + SHORTCUTS.map(&:count).reduce(0, :+) + 1
|
97
|
-
end
|
98
|
-
|
99
|
-
def offset_from_bottom
|
100
|
-
0
|
101
|
-
end
|
102
|
-
|
103
|
-
def scroll_manager
|
104
|
-
return @scroll_manager unless @scroll_manager.nil?
|
105
|
-
|
106
|
-
@scroll_manager = ScrollManager.new
|
107
|
-
@scroll_manager.delegate = self
|
108
|
-
@scroll_manager.after_move { refresh }
|
109
|
-
@scroll_manager
|
110
|
-
end
|
111
104
|
end
|
112
105
|
end
|
113
106
|
end
|
data/lib/twterm/tab/list_tab.rb
CHANGED
data/lib/twterm/tab/new/list.rb
CHANGED
@@ -3,6 +3,7 @@ module Twterm
|
|
3
3
|
module New
|
4
4
|
class List
|
5
5
|
include Base
|
6
|
+
include Scrollable
|
6
7
|
|
7
8
|
@@lists = nil
|
8
9
|
|
@@ -10,6 +11,10 @@ module Twterm
|
|
10
11
|
other.is_a?(self.class)
|
11
12
|
end
|
12
13
|
|
14
|
+
def drawable_item_count
|
15
|
+
(window.maxy - 2).div(3)
|
16
|
+
end
|
17
|
+
|
13
18
|
def initialize
|
14
19
|
super
|
15
20
|
|
@@ -17,50 +22,52 @@ module Twterm
|
|
17
22
|
refresh
|
18
23
|
end
|
19
24
|
|
25
|
+
def items
|
26
|
+
@@lists
|
27
|
+
end
|
28
|
+
|
20
29
|
def respond_to_key(key)
|
21
30
|
case key
|
22
31
|
when ?g
|
23
|
-
|
32
|
+
scroller.move_to_top
|
24
33
|
when ?G
|
25
|
-
|
34
|
+
scroller.move_to_bottom
|
26
35
|
when ?j, 14, Curses::Key::DOWN
|
27
|
-
|
36
|
+
scroller.move_down
|
28
37
|
when 10
|
29
38
|
return true if current_list.nil?
|
30
39
|
list_tab = Tab::ListTab.new(current_list.id)
|
31
40
|
TabManager.instance.switch(list_tab)
|
32
41
|
when ?k, 16, Curses::Key::UP
|
33
|
-
|
42
|
+
scroller.move_up
|
34
43
|
else
|
35
44
|
return false
|
36
45
|
end
|
37
46
|
true
|
38
47
|
end
|
39
48
|
|
40
|
-
|
41
|
-
|
42
|
-
def count
|
49
|
+
def total_item_count
|
43
50
|
@@lists.nil? ? 0 : @@lists.count
|
44
51
|
end
|
45
52
|
|
46
|
-
|
47
|
-
@@lists.nil? ? nil : @@lists[scroll_manager.index]
|
48
|
-
end
|
53
|
+
private
|
49
54
|
|
50
|
-
def
|
51
|
-
|
55
|
+
def current_list
|
56
|
+
@@lists.nil? ? nil : @@lists[scroller.index]
|
52
57
|
end
|
53
58
|
|
54
59
|
def show_lists
|
55
60
|
return if @@lists.nil?
|
56
61
|
|
57
|
-
|
62
|
+
index, offset = scroller.index, scroller.offset
|
63
|
+
|
64
|
+
drawable_items.each.with_index(0) do |list, i|
|
58
65
|
window.with_color(:black, :magenta) do
|
59
66
|
window.setpos(i * 3 + 5, 4)
|
60
67
|
window.addstr(' ')
|
61
68
|
window.setpos(i * 3 + 6, 4)
|
62
69
|
window.addstr(' ')
|
63
|
-
end if i
|
70
|
+
end if scroller.current_item?(i)
|
64
71
|
|
65
72
|
window.setpos(i * 3 + 5, 6)
|
66
73
|
window.addstr("#{list.full_name} (#{list.member_count} members / #{list.subscriber_count} subscribers)")
|
@@ -69,15 +76,6 @@ module Twterm
|
|
69
76
|
end
|
70
77
|
end
|
71
78
|
|
72
|
-
def scroll_manager
|
73
|
-
return @scroll_manager unless @scroll_manager.nil?
|
74
|
-
|
75
|
-
@scroll_manager = ScrollManager.new
|
76
|
-
@scroll_manager.delegate = self
|
77
|
-
@scroll_manager.after_move { refresh }
|
78
|
-
@scroll_manager
|
79
|
-
end
|
80
|
-
|
81
79
|
def update
|
82
80
|
window.setpos(2, 3)
|
83
81
|
window.bold { window.addstr('Open list tab') }
|
@@ -4,15 +4,24 @@ module Twterm
|
|
4
4
|
class Search
|
5
5
|
include Base
|
6
6
|
include Readline
|
7
|
+
include Scrollable
|
8
|
+
|
9
|
+
@@queries = []
|
7
10
|
|
8
11
|
def ==(other)
|
9
12
|
other.is_a?(self.class)
|
10
13
|
end
|
11
14
|
|
15
|
+
def drawable_item_count
|
16
|
+
(window.maxy - 2).div(3)
|
17
|
+
end
|
18
|
+
|
12
19
|
def initialize
|
13
20
|
super
|
14
21
|
|
15
22
|
@title = 'New tab'
|
23
|
+
|
24
|
+
update_saved_search
|
16
25
|
end
|
17
26
|
|
18
27
|
def invoke_input
|
@@ -29,27 +38,96 @@ module Twterm
|
|
29
38
|
query = (readline('> ') || '').strip
|
30
39
|
resetter.call
|
31
40
|
|
32
|
-
tab = query.nil? || query.empty? ? Tab::New::
|
41
|
+
tab = query.nil? || query.empty? ? Tab::New::Search.new : Tab::SearchTab.new(query)
|
33
42
|
TabManager.instance.switch(tab)
|
34
43
|
end
|
35
44
|
|
36
45
|
App.instance.register_interruption_handler do
|
37
46
|
input_thread.kill
|
38
47
|
resetter.call
|
39
|
-
tab = Tab::New::
|
48
|
+
tab = Tab::New::Search.new
|
40
49
|
TabManager.instance.switch(tab)
|
41
50
|
end
|
42
51
|
|
43
52
|
input_thread.join
|
44
53
|
end
|
45
54
|
|
46
|
-
def
|
47
|
-
|
55
|
+
def items
|
56
|
+
['<Input search query>'] + @@queries
|
57
|
+
end
|
58
|
+
|
59
|
+
def respond_to_key(key)
|
60
|
+
case key
|
61
|
+
when ?d, 4
|
62
|
+
10.times { scroller.move_down }
|
63
|
+
when ?g
|
64
|
+
scroller.move_to_top
|
65
|
+
when ?G
|
66
|
+
scroller.move_to_bottom
|
67
|
+
when 10
|
68
|
+
open_search_tab_with_current_query
|
69
|
+
when ?j, 14, Curses::Key::DOWN
|
70
|
+
scroller.move_down
|
71
|
+
when ?k, 16, Curses::Key::UP
|
72
|
+
scroller.move_up
|
73
|
+
when ?u, 21
|
74
|
+
10.times { scroller.move_up }
|
75
|
+
else
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
|
79
|
+
true
|
80
|
+
end
|
81
|
+
|
82
|
+
def total_item_count
|
83
|
+
@@queries.count + 1
|
48
84
|
end
|
49
85
|
|
50
86
|
private
|
51
87
|
|
52
|
-
|
88
|
+
alias_method :count, :total_item_count
|
89
|
+
|
90
|
+
def open_search_tab_with_current_query
|
91
|
+
index = scroller.index
|
92
|
+
|
93
|
+
if index == 0
|
94
|
+
invoke_input
|
95
|
+
else
|
96
|
+
query = @@queries[index - 1]
|
97
|
+
tab = Tab::SearchTab.new(query)
|
98
|
+
TabManager.instance.switch(tab)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def update
|
103
|
+
offset = scroller.offset
|
104
|
+
|
105
|
+
window.setpos(2, 3)
|
106
|
+
window.bold { window.addstr('Open search tab') }
|
107
|
+
|
108
|
+
drawable_items.each.with_index(0) do |query, i|
|
109
|
+
line = 3 * i + 5
|
110
|
+
|
111
|
+
window.with_color(:black, :magenta) do
|
112
|
+
window.setpos(line, 4)
|
113
|
+
window.addstr(' ')
|
114
|
+
window.setpos(line + 1, 4)
|
115
|
+
window.addstr(' ')
|
116
|
+
end if scroller.current_item?(i)
|
117
|
+
|
118
|
+
window.setpos(line, 6)
|
119
|
+
window.addstr(query)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def update_saved_search
|
124
|
+
return unless @@queries.empty?
|
125
|
+
|
126
|
+
Client.current.saved_search do |searches|
|
127
|
+
@@queries = searches.map(&:query)
|
128
|
+
refresh
|
129
|
+
end
|
130
|
+
end
|
53
131
|
end
|
54
132
|
end
|
55
133
|
end
|
data/lib/twterm/tab/new/start.rb
CHANGED
@@ -22,15 +22,10 @@ module Twterm
|
|
22
22
|
when 'S'
|
23
23
|
tab = Tab::New::Search.new
|
24
24
|
TabManager.instance.switch(tab)
|
25
|
-
tab.invoke_input
|
26
25
|
when 'U'
|
27
26
|
tab = Tab::New::User.new
|
28
27
|
TabManager.instance.switch(tab)
|
29
28
|
tab.invoke_input
|
30
|
-
when 'x'
|
31
|
-
tab = Tab::New::Track.new
|
32
|
-
TabManager.instance.switch(tab)
|
33
|
-
tab.invoke_input
|
34
29
|
else
|
35
30
|
return false
|
36
31
|
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Twterm
|
2
|
+
module Tab
|
3
|
+
module Scrollable
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
attr_reader :scroller
|
7
|
+
def_delegators :scroller, :drawable_items
|
8
|
+
|
9
|
+
def scroller
|
10
|
+
return @scroller unless @scroller.nil?
|
11
|
+
|
12
|
+
@scroller = Scroller.new
|
13
|
+
@scroller.delegate = self
|
14
|
+
@scroller.after_move { refresh }
|
15
|
+
@scroller
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
class Scroller
|
21
|
+
extend Forwardable
|
22
|
+
|
23
|
+
attr_reader :index, :offset
|
24
|
+
|
25
|
+
attr_accessor :delegate
|
26
|
+
def_delegators :delegate, :items, :total_item_count, :drawable_item_count
|
27
|
+
|
28
|
+
def after_move(&block)
|
29
|
+
add_hook(:after_move, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def current_item?(i)
|
33
|
+
index == offset + i
|
34
|
+
end
|
35
|
+
|
36
|
+
def cursor_free?
|
37
|
+
!!@cursor_free
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@index = 0
|
42
|
+
@offset = 0
|
43
|
+
@cursor_free_mode = false
|
44
|
+
end
|
45
|
+
|
46
|
+
def drawable_items
|
47
|
+
items.drop(offset).take(drawable_item_count)
|
48
|
+
end
|
49
|
+
|
50
|
+
def item_appended!
|
51
|
+
@index -= 1
|
52
|
+
@offset -= 1 if @offset > 0
|
53
|
+
end
|
54
|
+
|
55
|
+
def item_prepended!
|
56
|
+
@index += 1
|
57
|
+
@offset += 1
|
58
|
+
end
|
59
|
+
|
60
|
+
def move_down
|
61
|
+
return if count == 0 || index == count - 1
|
62
|
+
# return when there are no items or cursor is at the bottom
|
63
|
+
|
64
|
+
@index += 1
|
65
|
+
@offset += 1 if (cursor_free? || cursor_on_the_downside?) && !last_item_shown?
|
66
|
+
|
67
|
+
hook :after_move
|
68
|
+
end
|
69
|
+
|
70
|
+
def move_to_bottom
|
71
|
+
return if count == 0 || index == count - 1
|
72
|
+
|
73
|
+
@index = count - 1
|
74
|
+
@offset = [count - drawable_item_count + 1, 0].max
|
75
|
+
|
76
|
+
@offset += 1 until last_item_shown?
|
77
|
+
|
78
|
+
hook :after_move
|
79
|
+
end
|
80
|
+
|
81
|
+
def move_to_top
|
82
|
+
return if count.zero? || index.zero?
|
83
|
+
|
84
|
+
@index = 0
|
85
|
+
@offset = 0
|
86
|
+
|
87
|
+
hook :after_move
|
88
|
+
end
|
89
|
+
|
90
|
+
def move_up
|
91
|
+
return if count.zero? || index.zero?
|
92
|
+
|
93
|
+
@index -= 1
|
94
|
+
@offset -= 1 if cursor_on_the_upside? && !first_item_shown?
|
95
|
+
|
96
|
+
hook :after_move
|
97
|
+
end
|
98
|
+
|
99
|
+
def nth_item_drawable?(n)
|
100
|
+
n.between?(offset, offset + drawable_item_count)
|
101
|
+
end
|
102
|
+
|
103
|
+
def set_cursor_free!
|
104
|
+
@cursor_free = true
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
alias_method :count, :total_item_count
|
110
|
+
|
111
|
+
def add_hook(name, &block)
|
112
|
+
@hooks ||= {}
|
113
|
+
@hooks[name] = block
|
114
|
+
end
|
115
|
+
|
116
|
+
def cursor_on_the_downside?
|
117
|
+
drawable_item_count + offset - index < 4
|
118
|
+
end
|
119
|
+
|
120
|
+
def cursor_on_the_upside?
|
121
|
+
index - offset < 4
|
122
|
+
end
|
123
|
+
|
124
|
+
def first_item_shown?
|
125
|
+
offset.zero?
|
126
|
+
end
|
127
|
+
|
128
|
+
def last_item_shown?
|
129
|
+
total_item_count <= offset + drawable_item_count
|
130
|
+
end
|
131
|
+
|
132
|
+
def hook(name)
|
133
|
+
@hooks[name].call unless @hooks[name].nil?
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -2,6 +2,7 @@ module Twterm
|
|
2
2
|
module Tab
|
3
3
|
module StatusesTab
|
4
4
|
include Base
|
5
|
+
include Scrollable
|
5
6
|
|
6
7
|
def append(status)
|
7
8
|
fail ArgumentError,
|
@@ -12,14 +13,10 @@ module Twterm
|
|
12
13
|
@status_ids.unshift(status.id)
|
13
14
|
status.split(window.maxx - 4)
|
14
15
|
status.touch!
|
15
|
-
|
16
|
+
scroller.item_appended!
|
16
17
|
refresh
|
17
18
|
end
|
18
19
|
|
19
|
-
def count
|
20
|
-
grep_query.empty? ? @status_ids.count : statuses.count
|
21
|
-
end
|
22
|
-
|
23
20
|
def delete(status_id)
|
24
21
|
@status_ids.delete(status_id)
|
25
22
|
refresh
|
@@ -34,6 +31,14 @@ module Twterm
|
|
34
31
|
end
|
35
32
|
end
|
36
33
|
|
34
|
+
def drawable_item_count
|
35
|
+
statuses.reverse.drop(scroller.offset).lazy
|
36
|
+
.map { |s| s.split(window.maxx - 4).count + 2 }
|
37
|
+
.scan(0, :+)
|
38
|
+
.select { |l| l < window.maxy }
|
39
|
+
.count
|
40
|
+
end
|
41
|
+
|
37
42
|
def favorite
|
38
43
|
return if highlighted_status.nil?
|
39
44
|
|
@@ -56,26 +61,26 @@ module Twterm
|
|
56
61
|
|
57
62
|
if grep_query.empty?
|
58
63
|
reset_grep
|
59
|
-
elsif
|
64
|
+
elsif total_item_count == 0
|
60
65
|
Notifier.instance.show_error "No matches found: \"#{grep_query}\""
|
61
66
|
reset_grep
|
62
67
|
else
|
63
|
-
Notifier.instance.show_message "#{
|
64
|
-
|
68
|
+
Notifier.instance.show_message "#{total_item_count} statuses found: \"#{grep_query}\""
|
69
|
+
scroller.move_to_top
|
65
70
|
refresh
|
66
71
|
end
|
67
72
|
end
|
68
73
|
|
69
|
-
def grep_query
|
70
|
-
@grep_query || ''
|
71
|
-
end
|
72
|
-
|
73
74
|
def initialize
|
74
75
|
super
|
75
76
|
|
76
77
|
@status_ids = []
|
77
78
|
end
|
78
79
|
|
80
|
+
def items
|
81
|
+
statuses.reverse
|
82
|
+
end
|
83
|
+
|
79
84
|
def open_link
|
80
85
|
return if highlighted_status.nil?
|
81
86
|
|
@@ -92,7 +97,7 @@ module Twterm
|
|
92
97
|
@status_ids << status.id
|
93
98
|
status.split(window.maxx - 4)
|
94
99
|
status.touch!
|
95
|
-
|
100
|
+
scroller.item_prepended!
|
96
101
|
refresh
|
97
102
|
end
|
98
103
|
|
@@ -115,19 +120,19 @@ module Twterm
|
|
115
120
|
when ?c
|
116
121
|
show_conversation
|
117
122
|
when ?d, 4
|
118
|
-
10.times {
|
123
|
+
10.times { scroller.move_down }
|
119
124
|
when ?D
|
120
125
|
destroy_status
|
121
126
|
when ?F
|
122
127
|
favorite
|
123
128
|
when ?g
|
124
|
-
|
129
|
+
scroller.move_to_top
|
125
130
|
when ?G
|
126
|
-
|
131
|
+
scroller.move_to_bottom
|
127
132
|
when ?j, 14, Curses::Key::DOWN
|
128
|
-
|
133
|
+
scroller.move_down
|
129
134
|
when ?k, 16, Curses::Key::UP
|
130
|
-
|
135
|
+
scroller.move_up
|
131
136
|
when ?o
|
132
137
|
open_link
|
133
138
|
when ?r
|
@@ -137,7 +142,7 @@ module Twterm
|
|
137
142
|
when 18
|
138
143
|
fetch
|
139
144
|
when ?u, 21
|
140
|
-
10.times {
|
145
|
+
10.times { scroller.move_up }
|
141
146
|
when ?U
|
142
147
|
show_user
|
143
148
|
when ?/
|
@@ -185,33 +190,23 @@ module Twterm
|
|
185
190
|
statuses.reverse.take(100).each(&:touch!)
|
186
191
|
end
|
187
192
|
|
188
|
-
def
|
189
|
-
|
190
|
-
|
191
|
-
offset = scroll_manager.offset
|
192
|
-
index = scroll_manager.index
|
193
|
+
def total_item_count
|
194
|
+
grep_query.empty? ? @status_ids.count : statuses.count
|
195
|
+
end
|
193
196
|
|
194
|
-
|
197
|
+
def update
|
198
|
+
line = 0
|
195
199
|
|
196
|
-
|
200
|
+
scroller.drawable_items.each.with_index(0) do |status, i|
|
197
201
|
formatted_lines = status.split(window.maxx - 4).count
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
posy = current_line
|
204
|
-
|
205
|
-
if index == i
|
206
|
-
window.with_color(:black, :magenta) do
|
207
|
-
(formatted_lines + 1).times do |j|
|
208
|
-
window.setpos(posy + j, 0)
|
209
|
-
window.addch(' ')
|
210
|
-
end
|
202
|
+
window.with_color(:black, :magenta) do
|
203
|
+
(formatted_lines + 1).times do |j|
|
204
|
+
window.setpos(line + j, 0)
|
205
|
+
window.addch(' ')
|
211
206
|
end
|
212
|
-
end
|
207
|
+
end if scroller.current_item?(i)
|
213
208
|
|
214
|
-
window.setpos(
|
209
|
+
window.setpos(line, 2)
|
215
210
|
|
216
211
|
window.bold do
|
217
212
|
window.with_color(status.user.color) do
|
@@ -258,46 +253,24 @@ module Twterm
|
|
258
253
|
window.addch(' ')
|
259
254
|
end
|
260
255
|
|
261
|
-
status.split(window.maxx - 4).each do |
|
262
|
-
|
263
|
-
window.setpos(
|
264
|
-
window.addstr(
|
256
|
+
status.split(window.maxx - 4).each do |str|
|
257
|
+
line += 1
|
258
|
+
window.setpos(line, 2)
|
259
|
+
window.addstr(str)
|
265
260
|
end
|
266
261
|
|
267
|
-
|
262
|
+
line += 2
|
268
263
|
end
|
269
|
-
|
270
|
-
UserWindow.instance.update(highlighted_status.user) unless highlighted_status.nil?
|
271
264
|
end
|
272
265
|
|
273
266
|
private
|
274
267
|
|
275
|
-
def
|
276
|
-
|
277
|
-
Status.find(id)
|
278
|
-
end
|
279
|
-
|
280
|
-
def offset_from_bottom
|
281
|
-
return @offset_from_bottom unless @offset_from_bottom.nil?
|
282
|
-
|
283
|
-
height = 0
|
284
|
-
statuses.each.with_index(-1) do |status, i|
|
285
|
-
height += status.split(window.maxx - 4).count + 2
|
286
|
-
if height >= window.maxy
|
287
|
-
@offset_from_bottom = i
|
288
|
-
return i
|
289
|
-
end
|
290
|
-
end
|
291
|
-
count
|
268
|
+
def grep_query
|
269
|
+
@grep_query || ''
|
292
270
|
end
|
293
271
|
|
294
|
-
def
|
295
|
-
|
296
|
-
|
297
|
-
@scroll_manager = ScrollManager.new
|
298
|
-
@scroll_manager.delegate = self
|
299
|
-
@scroll_manager.after_move { refresh }
|
300
|
-
@scroll_manager
|
272
|
+
def highlighted_status
|
273
|
+
statuses[scroller.count - scroller.index - 1]
|
301
274
|
end
|
302
275
|
|
303
276
|
def sort
|
data/lib/twterm/tab/user_tab.rb
CHANGED
data/lib/twterm/version.rb
CHANGED
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: 1.0.
|
4
|
+
version: 1.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryota Kameoka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -159,6 +159,7 @@ files:
|
|
159
159
|
- lib/twterm/completion_mamanger.rb
|
160
160
|
- lib/twterm/config.rb
|
161
161
|
- lib/twterm/extensions/curses/window.rb
|
162
|
+
- lib/twterm/extensions/enumerator/lazy.rb
|
162
163
|
- lib/twterm/extensions/integer.rb
|
163
164
|
- lib/twterm/extensions/string.rb
|
164
165
|
- lib/twterm/history/base.rb
|
@@ -184,7 +185,7 @@ files:
|
|
184
185
|
- lib/twterm/tab/new/search.rb
|
185
186
|
- lib/twterm/tab/new/start.rb
|
186
187
|
- lib/twterm/tab/new/user.rb
|
187
|
-
- lib/twterm/tab/
|
188
|
+
- lib/twterm/tab/scrollable.rb
|
188
189
|
- lib/twterm/tab/search_tab.rb
|
189
190
|
- lib/twterm/tab/statuses_tab.rb
|
190
191
|
- lib/twterm/tab/timeline_tab.rb
|
@@ -1,84 +0,0 @@
|
|
1
|
-
module Twterm
|
2
|
-
module Tab
|
3
|
-
class ScrollManager
|
4
|
-
extend Forwardable
|
5
|
-
|
6
|
-
attr_reader :index, :offset
|
7
|
-
attr_accessor :last
|
8
|
-
|
9
|
-
attr_accessor :delegate
|
10
|
-
def_delegators :delegate, :count, :offset_from_bottom
|
11
|
-
|
12
|
-
def after_move(&block)
|
13
|
-
add_hook(:after_move, &block)
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@index = 0
|
18
|
-
@offset = 0
|
19
|
-
@last = 0
|
20
|
-
end
|
21
|
-
|
22
|
-
def item_appended!
|
23
|
-
@index -= 1
|
24
|
-
@offset -= 1 if @offset > 0
|
25
|
-
end
|
26
|
-
|
27
|
-
def item_prepended!
|
28
|
-
@index += 1
|
29
|
-
@offset += 1
|
30
|
-
end
|
31
|
-
|
32
|
-
def move_down
|
33
|
-
return if count == 0 || index == count - 1
|
34
|
-
|
35
|
-
@index = [index + 1, count - 1].min
|
36
|
-
@offset = [
|
37
|
-
offset + 1,
|
38
|
-
count - 1,
|
39
|
-
count - offset_from_bottom
|
40
|
-
].min if index > last - 4
|
41
|
-
|
42
|
-
hook :after_move
|
43
|
-
end
|
44
|
-
|
45
|
-
def move_to_bottom
|
46
|
-
return if count == 0 || index == count - 1
|
47
|
-
|
48
|
-
@index = count - 1
|
49
|
-
@offset = count - 1 - offset_from_bottom
|
50
|
-
|
51
|
-
hook :after_move
|
52
|
-
end
|
53
|
-
|
54
|
-
def move_to_top
|
55
|
-
return if count == 0 || index == 0
|
56
|
-
|
57
|
-
@index = 0
|
58
|
-
@offset = 0
|
59
|
-
|
60
|
-
hook :after_move
|
61
|
-
end
|
62
|
-
|
63
|
-
def move_up
|
64
|
-
return if count == 0 || index == 0
|
65
|
-
|
66
|
-
@index = [index - 1, 0].max
|
67
|
-
@offset = [offset - 1, 0].max if index - 4 < offset
|
68
|
-
|
69
|
-
hook :after_move
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
def add_hook(name, &block)
|
75
|
-
@hooks ||= {}
|
76
|
-
@hooks[name] = block
|
77
|
-
end
|
78
|
-
|
79
|
-
def hook(name)
|
80
|
-
@hooks[name].call unless @hooks[name].nil?
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|