yap-rawline 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21c58de0866271a9994af05648f35a469fa12fc8
4
- data.tar.gz: fb7199d0dd979db6e7ca55a7999fe74a5c98fbb9
3
+ metadata.gz: faf5249796b514e5aeed4e79a1de38d1559bf431
4
+ data.tar.gz: 893634b11c7c908ab2e983c51b5dac5996f46e58
5
5
  SHA512:
6
- metadata.gz: 9c0680fb3b2323de92e914f7cf798e46f6e11c68ddcec6e04dd505d14fcb75eddbe71120e34483c6c2486933689ff3e8fa4524b84b488a2db5324ee9074df295
7
- data.tar.gz: 00e4152cd8285b61aa5ec59fe9556179e14f9b7f9b2fd98b4ab3a6ce396c5f0a1cff1489b51ba8d55d7c1a24657c05cf473444d7b0ee1d664708f83877392742
6
+ metadata.gz: 1309021069574aba5c5b597342c9602caa858b1c211c88f79375d17380b7ab57a75f63198d151db981d2ffb90fb6805b606d6eb0a9007695c31f4baf2558fb37
7
+ data.tar.gz: 63ff4a40b302a64c1017a3b00993ce08750305e950109506f3a7a08b277ee9d40b8bb299ffe1fded63d034c8976e071a0c684f82b29b02a16e111fae4435138d
@@ -74,7 +74,7 @@ editor.bind(:ctrl_w){
74
74
  # History forward, but if at the end of the history then give user a
75
75
  # blank line rather than remain on the last command
76
76
  editor.bind(:down_arrow) {
77
- if editor.history.searching? && !editor.history.end?
77
+ if editor.history && !editor.history.end?
78
78
  editor.history_forward
79
79
  else
80
80
  editor.overwrite_line ""
@@ -90,13 +90,14 @@ module RawLine
90
90
  class Environment
91
91
  attr_accessor :keys, :completion_class, :history, :word_separator
92
92
  attr_accessor :keyboard_input_processors
93
+ attr_accessor :terminal
93
94
 
94
95
  # * <tt>@history_size</tt> - the size of the editor history buffer (30).
95
96
  # * <tt>@keys</tt> - the keys (arrays of character codes) bound to specific actions.
96
97
  # * <tt>@line_history_size</tt> - the size of the editor line history buffer (50).
97
- def initialize(env: nil)
98
+ def initialize(env: nil, terminal: nil)
98
99
  @env = env
99
- @keys = KeyBindings.new
100
+ @keys = KeyBindings.new(terminal: terminal)
100
101
  @keyboard_input_processors = []
101
102
 
102
103
  @completion_class = Completer
@@ -133,7 +134,7 @@ module RawLine
133
134
  @renderer = renderer
134
135
  @terminal = terminal
135
136
 
136
- @env_stack = [Environment.new]
137
+ @env_stack = [Environment.new(terminal: terminal)]
137
138
 
138
139
  @word_break_characters = " \t\n\"'@><=;|&{()}"
139
140
  @mode = :insert
@@ -537,9 +538,9 @@ module RawLine
537
538
  # with <tt>new_line</tt>, and optionally reset the cursor position to
538
539
  # <tt>position</tt>.
539
540
  #
540
- def overwrite_line(new_line, position=nil, options={})
541
- Treefell['editor'].puts "overwrite_line new_line=#{new_line} position=#{position} options=#{options.inspect}"
542
- if @line_editor.overwrite_line(new_line, position, options)
541
+ def overwrite_line(new_line, position: nil, highlight_up_to: nil)
542
+ Treefell['editor'].puts "overwrite_line new_line=#{new_line} position=#{position} highlight_up_to=#{highlight_up_to}"
543
+ if @line_editor.overwrite_line(new_line, position: position, highlight_up_to: highlight_up_to)
543
544
  @event_loop.add_event name: "render", source: focused_input_box
544
545
  end
545
546
  end
@@ -722,7 +723,7 @@ module RawLine
722
723
  @terminal.puts sprintf("%-#{max_index_width}d %s\n", i+1, item)
723
724
  end
724
725
  render(reset: true)
725
- overwrite_line(text, pos)
726
+ overwrite_line(text, position: pos)
726
727
  end
727
728
 
728
729
  #
@@ -813,7 +814,7 @@ module RawLine
813
814
  # terminal.puts "Character at Position: [#{text[pos].chr}] (#{text[pos]})" unless pos >= @line.length
814
815
  # terminal.puts "Current Word: [#{word[:text]}] (#{word[:start]} -- #{word[:end]})"
815
816
  clear_line
816
- overwrite_line(text, pos)
817
+ overwrite_line(text, position: pos)
817
818
  end
818
819
 
819
820
  def focus_input_box(box)
@@ -893,7 +894,7 @@ module RawLine
893
894
  return unless line
894
895
 
895
896
  cursor_position = nil
896
- overwrite_line(line, cursor_position, highlight_up_to: cursor_position)
897
+ overwrite_line(line, position: cursor_position, highlight_up_to: cursor_position)
897
898
  end
898
899
  end
899
900
 
@@ -904,7 +905,7 @@ module RawLine
904
905
  return unless line
905
906
 
906
907
  cursor_position = nil
907
- overwrite_line(line, cursor_position, highlight_up_to: cursor_position)
908
+ overwrite_line(line, position: cursor_position, highlight_up_to: cursor_position)
908
909
  end
909
910
  end
910
911
 
@@ -46,10 +46,6 @@ module RawLine
46
46
  @position = nil
47
47
  end
48
48
 
49
- def searching?
50
- !!@position
51
- end
52
-
53
49
  #
54
50
  # Resize the buffer, resetting <tt>@position</tt> to nil.
55
51
  #
@@ -61,6 +57,26 @@ module RawLine
61
57
  @position = nil
62
58
  end
63
59
 
60
+ def find_match_backward(text)
61
+ regex = to_regex(text)
62
+ offset = @position ? length - position : 0
63
+ reverse[offset..-1].detect.with_index do |item, index|
64
+ if item.match(regex)
65
+ @position = length - index - (offset + 1)
66
+ end
67
+ end
68
+ end
69
+
70
+ def find_match_forward(text)
71
+ regex = to_regex(text)
72
+ offset = @position ? @position + 1 : 0
73
+ self[offset..-1].detect.with_index do |item, index|
74
+ if item.match(regex)
75
+ @position = index + offset
76
+ end
77
+ end
78
+ end
79
+
64
80
  #
65
81
  # Clear the content of the buffer and reset <tt>@position</tt> to nil.
66
82
  #
@@ -74,7 +90,7 @@ module RawLine
74
90
  #
75
91
  def get
76
92
  return nil unless length > 0
77
- return nil unless @position
93
+ @position = length-1 unless @position
78
94
  at(@position).dup
79
95
  end
80
96
 
@@ -148,8 +164,7 @@ module RawLine
148
164
  # Add a new item to the buffer.
149
165
  #
150
166
  def push(item)
151
-
152
- if !@duplicates && self[-1] == item
167
+ if !@duplicates && include?(item)
153
168
  # skip adding this line
154
169
  return
155
170
  end
@@ -168,6 +183,12 @@ module RawLine
168
183
 
169
184
  alias << push
170
185
 
186
+ private
187
+
188
+ def to_regex(text)
189
+ return text if text.is_a?(Regexp)
190
+ /#{Regexp.escape(text)}/
191
+ end
171
192
  end
172
193
 
173
194
  end
data/lib/rawline/line.rb CHANGED
@@ -1,4 +1,4 @@
1
- #!usr/bin/env ruby
1
+ require 'ansi_string'
2
2
 
3
3
  #
4
4
  # line.rb
@@ -56,6 +56,10 @@ module RawLine
56
56
  @text = ANSIString.new(val)
57
57
  end
58
58
 
59
+ def text_up_to_position
60
+ text[0...position]
61
+ end
62
+
59
63
  #
60
64
  # Return information about the current word, as a Hash composed by the following
61
65
  # elements:
@@ -144,13 +144,14 @@ module RawLine
144
144
  # with <tt>new_line</tt>, and optionally reset the cursor position to
145
145
  # <tt>position</tt>.
146
146
  #
147
- def overwrite_line(new_line, position=nil, options={})
147
+ def overwrite_line(new_line, position: nil, highlight_up_to: nil)
148
+ position = @line.position if position == :preserve
148
149
  text = @line.text
149
150
  @highlighting = false
150
151
 
151
- if options[:highlight_up_to]
152
+ if highlight_up_to
152
153
  @highlighting = true
153
- new_line = highlight_text_up_to(new_line, options[:highlight_up_to])
154
+ new_line = highlight_text_up_to(new_line, highlight_up_to)
154
155
  end
155
156
 
156
157
  @line.position = position || new_line.length
@@ -1,3 +1,3 @@
1
1
  module RawLine
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
data/spec/editor_spec.rb CHANGED
@@ -38,6 +38,8 @@ describe RawLine::Editor do
38
38
  let(:dom) { RawLine::DomTree.new }
39
39
  let(:renderer) do
40
40
  instance_double(RawLine::Renderer,
41
+ pause: nil,
42
+ unpause: nil,
41
43
  render_cursor: nil,
42
44
  render: nil
43
45
  )
@@ -335,7 +337,7 @@ describe RawLine::Editor do
335
337
  input << "test #8a"
336
338
  input.rewind
337
339
  @editor.event_loop.tick
338
- @editor.overwrite_line("test #8b", 2)
340
+ @editor.overwrite_line("test #8b", position: 2)
339
341
  expect(@editor.line.text).to eq("test #8b")
340
342
  expect(@editor.line.position).to eq(2)
341
343
  end
@@ -3,8 +3,7 @@
3
3
  require_relative "../lib/rawline/history_buffer.rb"
4
4
 
5
5
  describe RawLine::HistoryBuffer do
6
-
7
- before :each do
6
+ before do
8
7
  @history = RawLine::HistoryBuffer.new(5)
9
8
  end
10
9
 
@@ -18,15 +17,15 @@ describe RawLine::HistoryBuffer do
18
17
  @history << "line #2"
19
18
  @history << "line #3"
20
19
  @history << "line #2"
21
- expect(@history).to eq(["line #1", "line #3", "line #2"])
20
+ expect(@history).to eq(["line #1", "line #2", "line #3"])
22
21
  @history.duplicates = true
23
22
  @history << "line #3"
24
- expect(@history).to eq(["line #1", "line #3", "line #2", "line #3"])
23
+ expect(@history).to eq(["line #1", "line #2", "line #3", "line #3"])
25
24
  @history.exclude = lambda { |i| i.match(/line #[456]/) }
26
25
  @history << "line #4"
27
26
  @history << "line #5"
28
27
  @history << "line #6"
29
- expect(@history).to eq(["line #1", "line #3", "line #2", "line #3"])
28
+ expect(@history).to eq(["line #1", "line #2", "line #3", "line #3"])
30
29
  end
31
30
 
32
31
  it "does not overflow" do
@@ -103,4 +102,83 @@ describe RawLine::HistoryBuffer do
103
102
  expect(@history.size).to eq(6)
104
103
  expect(@history.position).to eq(nil)
105
104
  end
105
+
106
+ describe 'finding matches in history, forward and backward' do
107
+ before do
108
+ @history.resize(100)
109
+ @history << 'echo foo'
110
+ @history << 'echo bar'
111
+ @history << 'echo baz'
112
+ @history << 'echo food'
113
+ @history << 'echo bark'
114
+ @history << 'echo bonanza'
115
+ end
116
+
117
+ describe '#find_match_backward' do
118
+ context 'when the position starts as nil' do
119
+ it 'finds the first item back that matches' do
120
+ @history.clear_position
121
+ expect(@history.find_match_backward('bonanza')).to eq 'echo bonanza'
122
+
123
+ @history.clear_position
124
+ expect(@history.find_match_backward('foo')).to eq 'echo food'
125
+ end
126
+
127
+ it 'can find consecutive matches, skipping unmatched items' do
128
+ @history.clear_position
129
+ expect(@history.find_match_backward('foo')).to eq 'echo food'
130
+ $z = true
131
+ expect(@history.find_match_backward('foo')).to eq 'echo foo'
132
+ end
133
+ end
134
+
135
+ context 'when the position starts as non-nil' do
136
+ it 'finds the first item back that matches from the current position' do
137
+ 3.times { @history.back }
138
+ expect(@history.find_match_backward('bar')).to eq 'echo bar'
139
+ end
140
+ end
141
+ end
142
+
143
+ describe '#find_match_forward' do
144
+ context 'when the position starts as nil' do
145
+ it 'finds the first item from the beginning that matches' do
146
+ @history.clear_position
147
+ expect(@history.find_match_forward('bar')).to eq 'echo bar'
148
+ expect(@history.position).to eq @history.index('echo bar')
149
+
150
+ @history.clear_position
151
+ expect(@history.find_match_forward('foo')).to eq 'echo foo'
152
+ expect(@history.position).to eq @history.index('echo foo')
153
+ end
154
+
155
+ it 'can find consecutive matches, skipping unmatched items' do
156
+ @history.clear_position
157
+ expect(@history.find_match_forward('foo')).to eq 'echo foo'
158
+ expect(@history.position).to eq @history.index('echo foo')
159
+
160
+ expect(@history.find_match_forward('foo')).to eq 'echo food'
161
+ expect(@history.position).to eq @history.index('echo food')
162
+ end
163
+ end
164
+
165
+ context 'when the position starts as non-nil' do
166
+ it 'finds the first item back that matches from the current position' do
167
+ 3.times { @history.back }
168
+ expect(@history.find_match_forward('bar')).to eq 'echo bark'
169
+ expect(@history.position).to eq @history.index('echo bark')
170
+ end
171
+ end
172
+
173
+ context 'when its gone all the way back, and we want to go forward' do
174
+ it 'd' do
175
+ @history.length.times do
176
+ @history.find_match_backward('bar')
177
+ end
178
+ expect(@history.find_match_forward('bar')).to eq 'echo bark'
179
+ end
180
+ end
181
+ end
182
+
183
+ end
106
184
  end
@@ -6,32 +6,23 @@ describe RawLine::KeycodeParser do
6
6
  subject(:keycode_parser) { described_class.new(keymap) }
7
7
  let(:keymap) { {} }
8
8
 
9
- describe "#parse_bytes" do
10
- def parse_bytes(bytes)
11
- keycode_parser.parse_bytes(bytes)
9
+ describe "#parse_bytes_into_sequences" do
10
+ let(:parse) do
11
+ keycode_parser.parse_bytes_into_sequences(bytes)
12
12
  end
13
+ let(:bytes){ fail 'Implement :bytes in context/describe for relevant example' }
13
14
 
14
15
  context "given a char that isn't in the keymap" do
16
+ let(:bytes){ "a".bytes }
15
17
  it "returns the byte as a keycode" do
16
- expect(parse_bytes(["a"])).to eq ["a".ord]
17
- end
18
- end
19
-
20
- context "given a char that isn't in the keymap" do
21
- it "returns the byte as a keycode" do
22
- expect(parse_bytes([97])).to eq ["a".ord]
23
- end
24
- end
25
-
26
- context "given multiple characters that aren't in the keymap" do
27
- it "returns the bytes as individual keycodes" do
28
- expect(parse_bytes(["a", "b", "C"])).to eq ["a", "b", "C"].map(&:ord)
18
+ expect(parse).to eq ["a"]
29
19
  end
30
20
  end
31
21
 
32
22
  context "given multiple characters that aren't in the keymap" do
23
+ let(:bytes){ "abC".bytes }
33
24
  it "returns the bytes as individual keycodes" do
34
- expect(parse_bytes([97, 98, 67])).to eq ["a", "b", "C"].map(&:ord)
25
+ expect(parse).to eq ["abC"]
35
26
  end
36
27
  end
37
28
 
@@ -39,9 +30,10 @@ describe RawLine::KeycodeParser do
39
30
  let(:keymap) do
40
31
  { backspace: [?\C-?.ord] }
41
32
  end
33
+ let(:bytes){ [127] }
42
34
 
43
35
  it "returns the bytes as a single key code" do
44
- expect(parse_bytes([127])).to eq [[127]]
36
+ expect(parse).to eq ["", [127]]
45
37
  end
46
38
  end
47
39
 
@@ -49,9 +41,10 @@ describe RawLine::KeycodeParser do
49
41
  let(:keymap) do
50
42
  { backspace: [?\C-?.ord] }
51
43
  end
44
+ let(:bytes) { [97, 127, 67] }
52
45
 
53
46
  it "returns the key codes appropriately" do
54
- expect(parse_bytes([97, 127, 67])).to eq [97, [127], 67]
47
+ expect(parse).to eq ["a", [127], "C"]
55
48
  end
56
49
  end
57
50
 
@@ -59,9 +52,10 @@ describe RawLine::KeycodeParser do
59
52
  let(:keymap) do
60
53
  { left_arrow: [?\e.ord, ?[.ord, ?D.ord] }
61
54
  end
55
+ let(:bytes) { [?\e.ord, ?[.ord, ?D.ord] }
62
56
 
63
57
  it "returns a single key code" do
64
- expect(parse_bytes([?\e.ord, ?[.ord, ?D.ord])).to eq [[?\e.ord, ?[.ord, ?D.ord]]
58
+ expect(parse).to eq ["", [27, 91, 68]]
65
59
  end
66
60
  end
67
61
 
@@ -69,9 +63,10 @@ describe RawLine::KeycodeParser do
69
63
  let(:keymap) do
70
64
  { left_arrow: [?\e.ord, ?[.ord, ?D.ord] }
71
65
  end
66
+ let(:bytes) { ["a".ord, ?\e.ord, ?[.ord, ?D.ord, "C".ord] }
72
67
 
73
68
  it "returns a keycodes appropriately" do
74
- expect(parse_bytes([97, ?\e.ord, ?[.ord, ?D.ord, 67])).to eq [97, [?\e.ord, ?[.ord, ?D.ord], 67]
69
+ expect(parse).to eq ["a", [?\e.ord, ?[.ord, ?D.ord], "C"]
75
70
  end
76
71
  end
77
72
 
data/spec/line_spec.rb CHANGED
@@ -8,7 +8,7 @@ require_relative "../lib/rawline/line.rb"
8
8
 
9
9
  describe RawLine::Line do
10
10
 
11
- before :each do
11
+ before do
12
12
  @line = RawLine::Line.new(5) {|l| l.prompt = "=>" }
13
13
  end
14
14
 
@@ -55,4 +55,17 @@ describe RawLine::Line do
55
55
  expect(@line.word).to eq({:start => 5, :end => 6, :text => "is"})
56
56
  end
57
57
 
58
+ describe '#text_up_to_position' do
59
+ subject(:line) { described_class.new }
60
+
61
+ it 'returns the text up to, but not including the current position' do
62
+ line << 'abcdefghij'
63
+ line.position = 1
64
+ expect(line.text_up_to_position).to eq('a')
65
+
66
+ line.position = 7
67
+ expect(line.text_up_to_position).to eq('abcdefg')
68
+ end
69
+ end
70
+
58
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yap-rawline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Cevasco
@@ -148,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  version: '0'
149
149
  requirements: []
150
150
  rubyforge_project:
151
- rubygems_version: 2.4.5.1
151
+ rubygems_version: 2.5.1
152
152
  signing_key:
153
153
  specification_version: 4
154
154
  summary: A library for defining custom key bindings and perform line editing operations