reline 0.1.8 → 0.1.9

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
  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.