reline 0.0.3 → 0.0.4

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: 5978554d657a91d17e199389ec2bf7dd1a505436bf0ea9c73478973c202d08c7
4
- data.tar.gz: cd5b28a0094e1af15c09617b8093550a81ed841ea1e9c9f3db9131eaca694217
3
+ metadata.gz: 5871c5fe137b41dce9b91a8c3507c871c00440393af055c1d546a17e2613fc1b
4
+ data.tar.gz: d6add41c6538d3cd07b813eab3b8998f57759209f821bf7950bf1a69d1f33966
5
5
  SHA512:
6
- metadata.gz: 2d21a0ee4c7a28ef7b7d32db350646b369719b2778d04cb4158cac1583a1f8c41010f55c1e8a81aa1954dce207e2048526cbfcbbebcb8624a3037ff18b0851e9
7
- data.tar.gz: f1d58c640a8cf6190c65a9bcf0898ecec70d9825f76fc68a28bcfe4300387eb6223f13d226689ecbd7d0fb248365e81a8df8fc8247452519abb163121684f4b3
6
+ metadata.gz: 105ed33c513bc997c46f6167da553f098f372272fe026b24afd2b472776dd840484afc0f284cd9d973b3db35940d84d99b4110b3d135d16944269c306ba33003
7
+ data.tar.gz: d28e6fe88b8a16022febeba31ead5a4e533f2a50fa65ed93328f35e5c0b2634b01b0e0b35efa278f6bbfd96b4fd42adee2d8e15e3f9d3092de5da2b61b1ef550
data/lib/reline/ansi.rb CHANGED
@@ -7,7 +7,7 @@ class Reline::ANSI
7
7
  [27, 91, 51, 126] => :key_delete, # Del
8
8
  [27, 91, 49, 126] => :ed_move_to_beg, # Home
9
9
  [27, 91, 52, 126] => :ed_move_to_end, # End
10
- }.each_key(&:freeze).freeze
10
+ }
11
11
 
12
12
  @@input = STDIN
13
13
  def self.input=(val)
@@ -1,7 +1,7 @@
1
1
  require 'timeout'
2
2
 
3
3
  class Reline::GeneralIO
4
- RAW_KEYSTROKE_CONFIG = {}.freeze
4
+ RAW_KEYSTROKE_CONFIG = {}
5
5
 
6
6
  @@buf = []
7
7
 
@@ -37,7 +37,7 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
37
37
  # 17 ^Q
38
38
  :ed_ignore,
39
39
  # 18 ^R
40
- :ed_insert,
40
+ :ed_search_prev_history,
41
41
  # 19 ^S
42
42
  :ed_ignore,
43
43
  # 20 ^T
@@ -60,6 +60,28 @@ class Reline::LineEditor
60
60
  reset_variables
61
61
  end
62
62
 
63
+ private def check_multiline_prompt(buffer, prompt)
64
+ if @vi_arg
65
+ prompt = "(arg: #{@vi_arg}) "
66
+ @rerender_all = true
67
+ elsif @searching_prompt
68
+ prompt = @searching_prompt
69
+ @rerender_all = true
70
+ else
71
+ prompt = @prompt
72
+ end
73
+ if @prompt_proc
74
+ prompt_list = @prompt_proc.(buffer)
75
+ prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
76
+ prompt = prompt_list[@line_index]
77
+ prompt_width = calculate_width(prompt, true)
78
+ [prompt, prompt_width, prompt_list]
79
+ else
80
+ prompt_width = calculate_width(prompt, true)
81
+ [prompt, prompt_width, nil]
82
+ end
83
+ end
84
+
63
85
  def reset(prompt = '', encoding = Encoding.default_external)
64
86
  @rest_height = (Reline::IOGate.get_screen_size.first - 1) - Reline::IOGate.cursor_pos.y
65
87
  @screen_size = Reline::IOGate.get_screen_size
@@ -76,28 +98,9 @@ class Reline::LineEditor
76
98
  @rerender_all = true
77
99
  rerender
78
100
  else
79
- special_prompt = nil
80
- if @vi_arg
81
- prompt = "(arg: #{@vi_arg}) "
82
- prompt_width = calculate_width(prompt)
83
- special_prompt = prompt
84
- elsif @searching_prompt
85
- prompt = @searching_prompt
86
- prompt_width = calculate_width(prompt)
87
- special_prompt = prompt
88
- else
89
- prompt = @prompt
90
- prompt_width = calculate_width(prompt, true)
91
- end
92
101
  back = 0
93
102
  new_buffer = whole_lines
94
- prompt_list = nil
95
- if @prompt_proc
96
- prompt_list = @prompt_proc.(new_buffer)
97
- prompt_list[@line_index] = special_prompt if special_prompt
98
- prompt = prompt_list[@line_index]
99
- prompt_width = calculate_width(prompt, true)
100
- end
103
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_buffer, prompt)
101
104
  new_buffer.each_with_index do |line, index|
102
105
  prompt_width = calculate_width(prompt_list[index], true) if @prompt_proc
103
106
  width = prompt_width + calculate_width(line)
@@ -312,30 +315,11 @@ class Reline::LineEditor
312
315
  move_cursor_up(@highest_in_all - 1 - @first_line_started_from)
313
316
  @menu_info = nil
314
317
  end
315
- special_prompt = nil
316
- if @vi_arg
317
- prompt = "(arg: #{@vi_arg}) "
318
- prompt_width = calculate_width(prompt)
319
- special_prompt = prompt
320
- elsif @searching_prompt
321
- prompt = @searching_prompt
322
- prompt_width = calculate_width(prompt)
323
- special_prompt = prompt
324
- else
325
- prompt = @prompt
326
- prompt_width = calculate_width(prompt, true)
327
- end
318
+ prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines, prompt)
328
319
  if @cleared
329
320
  Reline::IOGate.clear_screen
330
321
  @cleared = false
331
322
  back = 0
332
- prompt_list = nil
333
- if @prompt_proc
334
- prompt_list = @prompt_proc.(whole_lines)
335
- prompt_list[@line_index] = special_prompt if special_prompt
336
- prompt = prompt_list[@line_index]
337
- prompt_width = calculate_width(prompt, true)
338
- end
339
323
  modify_lines(whole_lines).each_with_index do |line, index|
340
324
  if @prompt_proc
341
325
  pr = prompt_list[index]
@@ -361,13 +345,7 @@ class Reline::LineEditor
361
345
  else
362
346
  new_lines = whole_lines
363
347
  end
364
- prompt_list = nil
365
- if @prompt_proc
366
- prompt_list = @prompt_proc.(new_lines)
367
- prompt_list[@line_index] = special_prompt if special_prompt
368
- prompt = prompt_list[@line_index]
369
- prompt_width = calculate_width(prompt, true)
370
- end
348
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines, prompt)
371
349
  all_height = new_lines.inject(0) { |result, line|
372
350
  result + calculate_height_by_width(prompt_width + calculate_width(line)) # TODO prompt_list
373
351
  }
@@ -431,13 +409,7 @@ class Reline::LineEditor
431
409
  Reline::IOGate.move_cursor_column(0)
432
410
  back = 0
433
411
  new_buffer = whole_lines
434
- prompt_list = nil
435
- if @prompt_proc
436
- prompt_list = @prompt_proc.(new_buffer)
437
- prompt_list[@line_index] = special_prompt if special_prompt
438
- prompt = prompt_list[@line_index]
439
- prompt_width = calculate_width(prompt, true)
440
- end
412
+ prompt, prompt_width, prompt_list = check_multiline_prompt(new_buffer, prompt)
441
413
  new_buffer.each_with_index do |line, index|
442
414
  prompt_width = calculate_width(prompt_list[index], true) if @prompt_proc
443
415
  width = prompt_width + calculate_width(line)
@@ -489,13 +461,7 @@ class Reline::LineEditor
489
461
  end
490
462
  line = modify_lines(whole_lines)[@line_index]
491
463
  if @is_multiline
492
- prompt_list = nil
493
- if @prompt_proc
494
- prompt_list = @prompt_proc.(whole_lines)
495
- prompt_list[@line_index] = special_prompt if special_prompt
496
- prompt = prompt_list[@line_index]
497
- prompt_width = calculate_width(prompt, true)
498
- end
464
+ prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines, prompt)
499
465
  if finished?
500
466
  # Always rerender on finish because output_modifier_proc may return a different output.
501
467
  render_partial(prompt, prompt_width, line)
@@ -1156,7 +1122,11 @@ class Reline::LineEditor
1156
1122
  alias_method :end_of_line, :ed_move_to_end
1157
1123
 
1158
1124
  private def ed_search_prev_history(key)
1159
- @line_backup_in_history = @line
1125
+ if @is_multiline
1126
+ @line_backup_in_history = whole_buffer
1127
+ else
1128
+ @line_backup_in_history = @line
1129
+ end
1160
1130
  searcher = Fiber.new do
1161
1131
  search_word = String.new(encoding: @encoding)
1162
1132
  multibyte_buf = String.new(encoding: 'ASCII-8BIT')
@@ -1191,11 +1161,25 @@ class Reline::LineEditor
1191
1161
  end
1192
1162
  end
1193
1163
  if hit
1194
- @searching_prompt = "(reverse-i-search)`%s': %s" % [search_word, hit]
1195
- @line = hit
1164
+ if @is_multiline
1165
+ @buffer_of_lines = hit.split("\n")
1166
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
1167
+ @line_index = @buffer_of_lines.size - 1
1168
+ @line = @buffer_of_lines.last
1169
+ @rerender_all = true
1170
+ @searching_prompt = "(reverse-i-search)`%s'" % [search_word]
1171
+ else
1172
+ @line = hit
1173
+ @searching_prompt = "(reverse-i-search)`%s': %s" % [search_word, hit]
1174
+ end
1196
1175
  last_hit = hit
1197
1176
  else
1198
- @searching_prompt = "(failed reverse-i-search)`%s': %s" % [search_word, last_hit]
1177
+ if @is_multiline
1178
+ @rerender_all = true
1179
+ @searching_prompt = "(failed reverse-i-search)`%s'" % [search_word]
1180
+ else
1181
+ @searching_prompt = "(failed reverse-i-search)`%s': %s" % [search_word, last_hit]
1182
+ end
1199
1183
  end
1200
1184
  end
1201
1185
  end
@@ -1223,13 +1207,24 @@ class Reline::LineEditor
1223
1207
  @cursor = @byte_pointer = 0
1224
1208
  else
1225
1209
  chr = key.is_a?(String) ? key : key.chr(Encoding::ASCII_8BIT)
1226
- if chr.match?(/[[:print:]]/)
1210
+ if chr.match?(/[[:print:]]/) or key == "\C-h".ord or key == 127
1227
1211
  searcher.resume(key)
1228
1212
  else
1229
1213
  if @history_pointer
1230
- @line = Reline::HISTORY[@history_pointer]
1214
+ line = Reline::HISTORY[@history_pointer]
1215
+ else
1216
+ line = @line_backup_in_history
1217
+ end
1218
+ if @is_multiline
1219
+ @line_backup_in_history = whole_buffer
1220
+ @buffer_of_lines = line.split("\n")
1221
+ @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
1222
+ @line_index = @buffer_of_lines.size - 1
1223
+ @line = @buffer_of_lines.last
1224
+ @rerender_all = true
1231
1225
  else
1232
- @line = @line_backup_in_history
1226
+ @line_backup_in_history = @line
1227
+ @line = line
1233
1228
  end
1234
1229
  @searching_prompt = nil
1235
1230
  @waiting_proc = nil
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
@@ -9,7 +9,15 @@ class Reline::Windows
9
9
  [224, 83] => :key_delete, # Del
10
10
  [224, 71] => :ed_move_to_beg, # Home
11
11
  [224, 79] => :ed_move_to_end, # End
12
- }.each_key(&:freeze).freeze
12
+ [ 0, 41] => :ed_unassigned, # input method on/off
13
+ [ 0, 72] => :ed_prev_history, # ↑
14
+ [ 0, 80] => :ed_next_history, # ↓
15
+ [ 0, 77] => :ed_next_char, # →
16
+ [ 0, 75] => :ed_prev_char, # ←
17
+ [ 0, 83] => :key_delete, # Del
18
+ [ 0, 71] => :ed_move_to_beg, # Home
19
+ [ 0, 79] => :ed_move_to_end # End
20
+ }
13
21
 
14
22
  if defined? JRUBY_VERSION
15
23
  require 'win32api'
@@ -54,6 +62,8 @@ class Reline::Windows
54
62
  end
55
63
 
56
64
  VK_MENU = 0x12
65
+ VK_LMENU = 0xA4
66
+ VK_CONTROL = 0x11
57
67
  VK_SHIFT = 0x10
58
68
  STD_INPUT_HANDLE = -10
59
69
  STD_OUTPUT_HANDLE = -11
@@ -82,6 +92,12 @@ class Reline::Windows
82
92
  end
83
93
  until @@kbhit.call == 0
84
94
  ret = @@getwch.call
95
+ if ret == 0 or ret == 0xE0
96
+ @@input_buf << ret
97
+ ret = @@getwch.call
98
+ @@input_buf << ret
99
+ return @@input_buf.shift
100
+ end
85
101
  begin
86
102
  bytes = ret.chr(Encoding::UTF_8).encode(Encoding.default_external).bytes
87
103
  @@input_buf.push(*bytes)
@@ -109,17 +125,19 @@ class Reline::Windows
109
125
  return @@output_buf.shift
110
126
  end
111
127
  input = getwch
112
- alt = (@@GetKeyState.call(VK_MENU) & 0x80) != 0
113
- shift_enter = !input.instance_of?(Array) && (@@GetKeyState.call(VK_SHIFT) & 0x80) != 0 && input == 0x0D
114
- if shift_enter
128
+ meta = (@@GetKeyState.call(VK_LMENU) & 0x80) != 0
129
+ control = (@@GetKeyState.call(VK_CONTROL) & 0x80) != 0
130
+ shift = (@@GetKeyState.call(VK_SHIFT) & 0x80) != 0
131
+ force_enter = !input.instance_of?(Array) && (control or shift) && input == 0x0D
132
+ if force_enter
115
133
  # It's treated as Meta+Enter on Windows
116
134
  @@output_buf.push("\e".ord)
117
135
  @@output_buf.push(input)
118
136
  else
119
137
  case input
120
138
  when 0x00
121
- getwch
122
- alt = false
139
+ meta = false
140
+ @@output_buf.push(input)
123
141
  input = getwch
124
142
  @@output_buf.push(*input)
125
143
  when 0xE0
@@ -132,7 +150,7 @@ class Reline::Windows
132
150
  @@output_buf.push(input)
133
151
  end
134
152
  end
135
- if alt
153
+ if meta
136
154
  "\e".ord
137
155
  else
138
156
  @@output_buf.shift
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.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-07 00:00:00.000000000 Z
11
+ date: 2019-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler