dispel 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4ed33d439836221d928810d9b299e39403683091
4
- data.tar.gz: dda5b216de46c2e5d40274decae00e6e9fd23fb2
3
+ metadata.gz: 79c60ba642498ac215494cfbee428f1630889047
4
+ data.tar.gz: 16118c62b8d5a73823ceb455a6ab06caecef8c60
5
5
  SHA512:
6
- metadata.gz: c6eed6e4a0660ee51c74a60bbc628fe53738582252ee37ff53ef70ccb8601f55b8006c10a5a81390f686f35a3675a479760380c59dbc684ac1f5e78b0d0fc988
7
- data.tar.gz: 2d38879e158d5cfbc70d3e58ac7ef0489def7c4bd17fd426025ec0914076be479b52a23cf442fdbfc050320949ff96d8405c4f7551ee49d01f644a4857d0a109
6
+ metadata.gz: 3edd4d1fa6ea46eca07fc549b2a4d8eef6cf672d115599bf33279ea70c4fab77f37dd16961e09197ce5aaf06efb984c707e7f48d2d6e7b5d58cbea4ec6ae6a31
7
+ data.tar.gz: 83fea979ec2dd1ff2ef9191466bad84d680cd76ffcbaa699f55172f672aaa7166159d8a1a53d71e2c6119ddf24e5af5dc86277b7e23e3507dfabde1a39385b73
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -9,25 +9,42 @@ module Dispel
9
9
  SEQUENCE_TIMEOUT = 0.005
10
10
  NOTHING = (2**32 - 1) # getch returns this as 'nothing' on 1.8 but nil on 1.9.2
11
11
  A_TO_Z = ('a'..'z').to_a
12
+ DEFAULT_INPUT = lambda { Curses.getch }
12
13
 
13
14
  def self.input(&block)
14
15
  @input = block
15
16
  end
16
17
 
17
- def self.output
18
- input { Curses.getch } unless @input # keep input replaceable for tests, but default to curses
19
-
18
+ def self.output(options={}, &block)
20
19
  @sequence = []
21
20
  @started = Time.now.to_f
21
+ timeout = options[:timeout]
22
+
23
+ if timeout && SEQUENCE_TIMEOUT > timeout
24
+ raise "Timeout must be higher then SEQUENCE_TIMEOUT (#{SEQUENCE_TIMEOUT})"
25
+ end
22
26
 
23
27
  loop do
28
+ @now = Time.now.to_f
29
+ @elapsed = @now - @started
30
+
24
31
  key = fetch_user_input
25
- if sequence_finished?
26
- sequence_to_keys(@sequence).each{|k| yield k }
32
+
33
+ # finish previous sequence
34
+ if @sequence.any? and @elapsed > SEQUENCE_TIMEOUT
35
+ sequence_to_keys(@sequence).each(&block)
27
36
  @sequence = []
28
37
  end
29
- next unless key
30
- append_to_sequence key
38
+
39
+ if key # start new sequence
40
+ @started = @now
41
+ @sequence << key
42
+ elsif timeout and @elapsed > timeout
43
+ @started = @now
44
+ yield :timeout
45
+ else
46
+ sleep SEQUENCE_TIMEOUT # nothing happening -> sleep a bit to save cpu
47
+ end
31
48
  end
32
49
  end
33
50
 
@@ -127,19 +144,9 @@ module Dispel
127
144
  end
128
145
 
129
146
  def self.fetch_user_input
130
- key = @input.call or return
147
+ key = (@input || DEFAULT_INPUT).call || NOTHING
131
148
  key = key.ord unless IS_18
132
- if key >= NOTHING
133
- # nothing happening -> sleep a bit to save cpu
134
- sleep SEQUENCE_TIMEOUT
135
- return
136
- end
137
- key
138
- end
139
-
140
- def self.append_to_sequence(key)
141
- @started = Time.now.to_f
142
- @sequence << key
149
+ key if key < NOTHING
143
150
  end
144
151
 
145
152
  def self.bytes_to_string(bytes)
@@ -176,10 +183,6 @@ module Dispel
176
183
  127 < byte and byte < 256
177
184
  end
178
185
 
179
- def self.sequence_finished?
180
- @sequence.size != 0 and (Time.now.to_f - @started) > SEQUENCE_TIMEOUT
181
- end
182
-
183
186
  # paste of multiple \n or \n in text would cause weird indentation
184
187
  def self.needs_paste_fix?(sequence)
185
188
  sequence.size > 1 and sequence.include?(ENTER)
data/lib/dispel/screen.rb CHANGED
@@ -35,11 +35,8 @@ module Dispel
35
35
  Curses.stdscr.maxy
36
36
  end
37
37
 
38
- def clear_cache
39
- @cache.clear
40
- end
41
-
42
38
  def draw(view, style_map=[], cursor=[0,0])
39
+ @cache.clear if dimensions_changed?
43
40
  draw_view(view, style_map)
44
41
  Curses.setpos(*cursor) # cursor has to always be set or it ends in random position
45
42
  end
@@ -80,7 +77,7 @@ module Dispel
80
77
  # position at start of line and draw
81
78
  Curses.setpos(line_number,0)
82
79
  Dispel::StyleMap.styled(line, styles).each do |style, part|
83
- Curses.attrset self.class.curses_style(style, color?, options)
80
+ Curses.attrset curses_style(style)
84
81
  Curses.addstr part
85
82
  end
86
83
 
@@ -97,33 +94,41 @@ module Dispel
97
94
  yield # render the line
98
95
  end
99
96
 
97
+ def dimensions_changed?
98
+ current_dimensions = [columns, lines]
99
+ @old_dimensions != current_dimensions
100
+ @old_dimensions = current_dimensions
101
+ end
102
+
103
+ def curses_style(style)
104
+ @style ||= {}
105
+ @style[style] ||= self.class.curses_style(style, color?, options)
106
+ end
107
+
100
108
  class << self
101
- # TODO maybe instance and simpler caching...
102
109
  def curses_style(style, colors, options={})
103
- Tools.memoize(:curses_style, style, colors) do
104
- if colors
105
- foreground = options[:foreground] || '#ffffff'
106
- background = options[:background] || '#000000'
107
-
108
- foreground, background = if style == :normal
109
- [foreground, background]
110
- elsif style == :reverse
111
- ['#000000', '#ffffff']
112
- else
113
- # :red or [:red, :blue]
114
- f,b = style
115
- [f || foreground, b || background]
116
- end
117
-
118
- foreground = html_to_terminal_color(foreground)
119
- background = html_to_terminal_color(background)
120
- color_id(foreground, background)
121
- else # no colors
122
- if style == :reverse
123
- Curses::A_REVERSE
124
- else
125
- Curses::A_NORMAL
126
- end
110
+ if colors
111
+ foreground = options[:foreground] || '#ffffff'
112
+ background = options[:background] || '#000000'
113
+
114
+ foreground, background = if style == :normal
115
+ [foreground, background]
116
+ elsif style == :reverse
117
+ ['#000000', '#ffffff']
118
+ else
119
+ # :red or [:red, :blue]
120
+ f,b = style
121
+ [f || foreground, b || background]
122
+ end
123
+
124
+ foreground = html_to_terminal_color(foreground)
125
+ background = html_to_terminal_color(background)
126
+ color_id(foreground, background)
127
+ else # no colors
128
+ if style == :reverse
129
+ Curses::A_REVERSE
130
+ else
131
+ Curses::A_NORMAL
127
132
  end
128
133
  end
129
134
  end
@@ -131,7 +136,8 @@ module Dispel
131
136
  # create a new color from foreground+background or reuse old
132
137
  # and return color-id
133
138
  def color_id(foreground, background)
134
- Tools.memoize(:color_id, foreground, background) do
139
+ @color_ids ||= {}
140
+ @color_ids[[foreground, background]] ||= begin
135
141
  # make a new pair with a unique id
136
142
  @@max_color_id ||= 0
137
143
  id = (@@max_color_id += 1)
data/lib/dispel/tools.rb CHANGED
@@ -12,19 +12,19 @@ module Dispel
12
12
  result.empty? ? [''] : result
13
13
  end
14
14
 
15
- def memoize(*args)
16
- key = args.map(&:to_s).join("-")
17
- @memoize ||= {}
18
- if @memoize.key?(key)
19
- @memoize[key]
20
- else
21
- @memoize[key] = yield
22
- end
23
- end
24
-
25
15
  def last_element(range)
26
16
  range.exclude_end? ? range.last.pred : range.last
27
17
  end
18
+
19
+ # http://grosser.it/2010/12/31/ruby-string-indexes-indices-find-all-indexes-in-a-string
20
+ def indexes(string, needle)
21
+ found = []
22
+ current_index = -1
23
+ while current_index = string.index(needle, current_index+1)
24
+ found << current_index
25
+ end
26
+ found
27
+ end
28
28
  end
29
29
  end
30
30
  end
@@ -1,3 +1,3 @@
1
1
  module Dispel
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dispel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
metadata.gz.sig CHANGED
Binary file