reline 0.1.8 → 0.1.9

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
  SHA256:
3
- metadata.gz: 89f055454b502262f43495a2d8de12ba033259287a4c09e7c93afeb0462c9c33
4
- data.tar.gz: 6c6f081e14d699faed9ac7ba08001dac978318535f58458fd2c777db56b57b50
3
+ metadata.gz: 981888e54748ace72084309bf4d0b832503970956188b3865629da1c577b5edb
4
+ data.tar.gz: 11815b8b07d66ef247ab83e37d6c8884fdc4745e681b298237e2e32b631c4cbb
5
5
  SHA512:
6
- metadata.gz: 6bd17793312ff9f2996ce08ebada091005c7efd9ff1d0ef007ea982ee5e74ee03a83fb0bb7c975c6da747db712a3837d14c108fd7de087094f1db37e051876aa
7
- data.tar.gz: 148dd6767b1aae9a295d334445957b64e6f6a46b8941a10517e5d4567a29eac369fe3843c6c8c1bb5fd66d1165c82988316b030eb05080517bb7105bc5174281
6
+ metadata.gz: 8b9df7fa6a4e7196773314b8e5287021fbdfcdd81372740c0c32d60c03cc4aed8fda02f5b14e337c428c160b1ff5a2c4144f5a5866af8f57e50fcb25b51b9099
7
+ data.tar.gz: 50920eaeb2ef94d831c4eb4d798e41ccf9c7a826f237b1fc3343969e6af2ea05332cb38e4638c2fa439a29231a3789b0f4d0ee731d3106aaa6f6d08b12cbcb39
@@ -179,6 +179,7 @@ class Reline::LineEditor
179
179
  @vi_arg = nil
180
180
  @waiting_proc = nil
181
181
  @waiting_operator_proc = nil
182
+ @waiting_operator_vi_arg = nil
182
183
  @completion_journey_data = nil
183
184
  @completion_state = CompletionState::NORMAL
184
185
  @perfect_matched = nil
@@ -186,6 +187,7 @@ class Reline::LineEditor
186
187
  @first_prompt = true
187
188
  @searching_prompt = nil
188
189
  @first_char = true
190
+ @add_newline_to_end_of_buffer = false
189
191
  @eof = false
190
192
  @continuous_insertion_buffer = String.new(encoding: @encoding)
191
193
  reset_line
@@ -351,7 +353,22 @@ class Reline::LineEditor
351
353
  end
352
354
  new_highest_in_this = calculate_height_by_width(prompt_width + calculate_width(@line.nil? ? '' : @line))
353
355
  # FIXME: end of logical line sometimes breaks
354
- if @previous_line_index or new_highest_in_this != @highest_in_this
356
+ if @add_newline_to_end_of_buffer
357
+ scroll_down(1)
358
+ new_lines = whole_lines(index: @previous_line_index, line: @line)
359
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines, prompt)
360
+ @buffer_of_lines[@previous_line_index] = @line
361
+ @line = @buffer_of_lines[@line_index]
362
+ render_partial(prompt, prompt_width, @line, false)
363
+ @cursor = @cursor_max = calculate_width(@line)
364
+ @byte_pointer = @line.bytesize
365
+ @highest_in_all += @highest_in_this
366
+ @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max)
367
+ @first_line_started_from += @started_from + 1
368
+ @started_from = calculate_height_by_width(prompt_width + @cursor) - 1
369
+ @previous_line_index = nil
370
+ @add_newline_to_end_of_buffer = false
371
+ elsif @previous_line_index or new_highest_in_this != @highest_in_this
355
372
  if @previous_line_index
356
373
  new_lines = whole_lines(index: @previous_line_index, line: @line)
357
374
  else
@@ -698,6 +715,7 @@ class Reline::LineEditor
698
715
  if @waiting_operator_proc
699
716
  if VI_MOTIONS.include?(method_symbol)
700
717
  old_cursor, old_byte_pointer = @cursor, @byte_pointer
718
+ @vi_arg = @waiting_operator_vi_arg if @waiting_operator_vi_arg > 1
701
719
  block.(true)
702
720
  unless @waiting_proc
703
721
  cursor_diff, byte_pointer_diff = @cursor - old_cursor, @byte_pointer - old_byte_pointer
@@ -721,6 +739,8 @@ class Reline::LineEditor
721
739
  block.(false)
722
740
  end
723
741
  @waiting_operator_proc = nil
742
+ @waiting_operator_vi_arg = nil
743
+ @vi_arg = nil
724
744
  else
725
745
  block.(false)
726
746
  end
@@ -1112,6 +1132,9 @@ class Reline::LineEditor
1112
1132
 
1113
1133
  private def key_newline(key)
1114
1134
  if @is_multiline
1135
+ if (@buffer_of_lines.size - 1) == @line_index and @line.bytesize == @byte_pointer
1136
+ @add_newline_to_end_of_buffer = true
1137
+ end
1115
1138
  next_line = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer)
1116
1139
  cursor_line = @line.byteslice(0, @byte_pointer)
1117
1140
  insert_new_line(cursor_line, next_line)
@@ -2088,7 +2111,7 @@ class Reline::LineEditor
2088
2111
  @cursor = 0
2089
2112
  end
2090
2113
 
2091
- private def vi_change_meta(key)
2114
+ private def vi_change_meta(key, arg: 1)
2092
2115
  @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
2093
2116
  if byte_pointer_diff > 0
2094
2117
  @line, cut = byteslice!(@line, @byte_pointer, byte_pointer_diff)
@@ -2101,9 +2124,10 @@ class Reline::LineEditor
2101
2124
  @byte_pointer += byte_pointer_diff if byte_pointer_diff < 0
2102
2125
  @config.editing_mode = :vi_insert
2103
2126
  }
2127
+ @waiting_operator_vi_arg = arg
2104
2128
  end
2105
2129
 
2106
- private def vi_delete_meta(key)
2130
+ private def vi_delete_meta(key, arg: 1)
2107
2131
  @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
2108
2132
  if byte_pointer_diff > 0
2109
2133
  @line, cut = byteslice!(@line, @byte_pointer, byte_pointer_diff)
@@ -2115,9 +2139,10 @@ class Reline::LineEditor
2115
2139
  @cursor_max -= cursor_diff.abs
2116
2140
  @byte_pointer += byte_pointer_diff if byte_pointer_diff < 0
2117
2141
  }
2142
+ @waiting_operator_vi_arg = arg
2118
2143
  end
2119
2144
 
2120
- private def vi_yank(key)
2145
+ private def vi_yank(key, arg: 1)
2121
2146
  @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff|
2122
2147
  if byte_pointer_diff > 0
2123
2148
  cut = @line.byteslice(@byte_pointer, byte_pointer_diff)
@@ -2126,6 +2151,7 @@ class Reline::LineEditor
2126
2151
  end
2127
2152
  copy_for_vi(cut)
2128
2153
  }
2154
+ @waiting_operator_vi_arg = arg
2129
2155
  end
2130
2156
 
2131
2157
  private def vi_list_or_eof(key)
@@ -35,11 +35,16 @@ class Reline::Unicode
35
35
  }
36
36
  EscapedChars = EscapedPairs.keys.map(&:chr)
37
37
 
38
- CSI_REGEXP = /\e\[[\d;]*[ABCDEFGHJKSTfminsuhl]/
39
- OSC_REGEXP = /\e\]\d+(?:;[^;]+)*\a/
40
38
  NON_PRINTING_START = "\1"
41
39
  NON_PRINTING_END = "\2"
42
- WIDTH_SCANNER = /\G(?:#{NON_PRINTING_START}|#{NON_PRINTING_END}|#{CSI_REGEXP}|#{OSC_REGEXP}|\X)/
40
+ CSI_REGEXP = /\e\[[\d;]*[ABCDEFGHJKSTfminsuhl]/
41
+ OSC_REGEXP = /\e\]\d+(?:;[^;]+)*\a/
42
+ WIDTH_SCANNER = /\G(?:(#{NON_PRINTING_START})|(#{NON_PRINTING_END})|(#{CSI_REGEXP})|(#{OSC_REGEXP})|(\X))/o
43
+ NON_PRINTING_START_INDEX = 0
44
+ NON_PRINTING_END_INDEX = 1
45
+ CSI_REGEXP_INDEX = 2
46
+ OSC_REGEXP_INDEX = 3
47
+ GRAPHEME_CLUSTER_INDEX = 4
43
48
 
44
49
  def self.get_mbchar_byte_size_by_first_char(c)
45
50
  # Checks UTF-8 character byte size
@@ -89,15 +94,25 @@ class Reline::Unicode
89
94
  | #{ EastAsianWidth::TYPE_NA }
90
95
  | #{ EastAsianWidth::TYPE_N }
91
96
  )
97
+ | (?<ambiguous_width>
98
+ #{EastAsianWidth::TYPE_A}
99
+ )
92
100
  /x
93
101
 
94
102
  def self.get_mbchar_width(mbchar)
103
+ ord = mbchar.ord
104
+ if (0x00 <= ord and ord <= 0x1F)
105
+ return 2
106
+ elsif (0x20 <= ord and ord <= 0x7E)
107
+ return 1
108
+ end
95
109
  m = mbchar.encode(Encoding::UTF_8).match(MBCharWidthRE)
96
110
  case
97
111
  when m[:width_2_1], m[:width_2_2] then 2
98
112
  when m[:width_3] then 3
99
113
  when m[:width_0] then 0
100
114
  when m[:width_1] then 1
115
+ when m[:ambiguous_width] then Reline.ambiguous_width
101
116
  else
102
117
  nil
103
118
  end
@@ -109,13 +124,14 @@ class Reline::Unicode
109
124
  rest = str.encode(Encoding::UTF_8)
110
125
  in_zero_width = false
111
126
  rest.scan(WIDTH_SCANNER) do |gc|
112
- case gc
113
- when NON_PRINTING_START
127
+ case
128
+ when gc[NON_PRINTING_START_INDEX]
114
129
  in_zero_width = true
115
- when NON_PRINTING_END
130
+ when gc[NON_PRINTING_END_INDEX]
116
131
  in_zero_width = false
117
- when CSI_REGEXP, OSC_REGEXP
118
- else
132
+ when gc[CSI_REGEXP_INDEX], gc[OSC_REGEXP_INDEX]
133
+ when gc[GRAPHEME_CLUSTER_INDEX]
134
+ gc = gc[GRAPHEME_CLUSTER_INDEX]
119
135
  unless in_zero_width
120
136
  width += get_mbchar_width(gc)
121
137
  end
@@ -136,14 +152,17 @@ class Reline::Unicode
136
152
  rest = str.encode(Encoding::UTF_8)
137
153
  in_zero_width = false
138
154
  rest.scan(WIDTH_SCANNER) do |gc|
139
- case gc
140
- when NON_PRINTING_START
155
+ case
156
+ when gc[NON_PRINTING_START_INDEX]
141
157
  in_zero_width = true
142
- when NON_PRINTING_END
158
+ when gc[NON_PRINTING_END_INDEX]
143
159
  in_zero_width = false
144
- when CSI_REGEXP, OSC_REGEXP
145
- lines.last << gc
146
- else
160
+ when gc[CSI_REGEXP_INDEX]
161
+ lines.last << gc[CSI_REGEXP_INDEX]
162
+ when gc[OSC_REGEXP_INDEX]
163
+ lines.last << gc[OSC_REGEXP_INDEX]
164
+ when gc[GRAPHEME_CLUSTER_INDEX]
165
+ gc = gc[GRAPHEME_CLUSTER_INDEX]
147
166
  unless in_zero_width
148
167
  mbchar_width = get_mbchar_width(gc)
149
168
  if (width += mbchar_width) > max_width
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.1.8'
2
+ VERSION = '0.1.9'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-09 00:00:00.000000000 Z
11
+ date: 2020-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  - !ruby/object:Gem::Version
128
128
  version: '0'
129
129
  requirements: []
130
- rubygems_version: 3.1.4
130
+ rubygems_version: 3.1.2
131
131
  signing_key:
132
132
  specification_version: 4
133
133
  summary: Alternative GNU Readline or Editline implementation by pure Ruby.