reline 0.5.6 → 0.5.8

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: a87d2a8f8718292be59386f13b873af0fa94cb20f6837761332174c413dc7755
4
- data.tar.gz: 342c0dfbcf1e99af3c31ac4370f576e6a447728b2942328db1fc2a8a5b458b9e
3
+ metadata.gz: bcccc644594f9c2e4b9ae0eb743c2ae293ef084e96a8d9bd032b76825111c01b
4
+ data.tar.gz: b5ab239a3d20925d4fbd8fb827908fa3e4fa70298a172e32e9b2b4de59dc767e
5
5
  SHA512:
6
- metadata.gz: 0031f7bd3660b7adda54149c1e15da1d1d2f9ef5c7e240828c9a1f3337d0c7bf2e1796c5ba6f61f1352c18819225697e4dd7c32149ff3297f65ddf0fd8f06e82
7
- data.tar.gz: ea8bfe21ce43dbd3f1f6fa23d1d1a1948005cdda278485bba9010060f1ad1e3900c749e1a2966caf39f892c4c38692bc4abe8283425e3c3138e273f65b170ca9
6
+ metadata.gz: 9bce894711da0253bf9b3f0eb192ff64947d591edd00f9094430431eb470fade4d02f3f8b529d364cdd7124d7f5a5203ea755be41dbfda890e37654aca430706
7
+ data.tar.gz: eed500ad148a1f83e3de03e6d7daaf5d250ba3ea25d47d24070e749dfd44a7d900b83474dd0b427faee74bad883dab97b7af1984a7fb7209e1819fd416d4381b
data/README.md CHANGED
@@ -15,7 +15,7 @@ Reline is compatible with the API of Ruby's stdlib 'readline', GNU Readline and
15
15
 
16
16
  It's compatible with the readline standard library.
17
17
 
18
- See [the document of readline stdlib](https://ruby-doc.org/stdlib/libdoc/readline/rdoc/Readline.html) or [bin/example](https://github.com/ruby/reline/blob/master/bin/example).
18
+ See [the document of readline stdlib](https://ruby-doc.org/stdlib/exts/readline/Readline.html) or [bin/example](https://github.com/ruby/reline/blob/master/bin/example).
19
19
 
20
20
  ### Multi-line editing mode
21
21
 
data/lib/reline/ansi.rb CHANGED
@@ -235,7 +235,7 @@ class Reline::ANSI
235
235
  s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
236
236
  return s if s[0] > 0 && s[1] > 0
237
237
  [24, 80]
238
- rescue Errno::ENOTTY
238
+ rescue Errno::ENOTTY, Errno::ENODEV
239
239
  [24, 80]
240
240
  end
241
241
 
data/lib/reline/config.rb CHANGED
@@ -182,9 +182,10 @@ class Reline::Config
182
182
  next if if_stack.any? { |_no, skip| skip }
183
183
 
184
184
  case line
185
- when /^set +([^ ]+) +([^ ]+)/i
186
- var, value = $1.downcase, $2
187
- bind_variable(var, value)
185
+ when /^set +([^ ]+) +(.+)/i
186
+ # value ignores everything after a space, raw_value does not.
187
+ var, value, raw_value = $1.downcase, $2.partition(' ').first, $2
188
+ bind_variable(var, value, raw_value)
188
189
  next
189
190
  when /\s*("#{KEYSEQ_PATTERN}+")\s*:\s*(.*)\s*$/o
190
191
  key, func_name = $1, $2
@@ -234,7 +235,7 @@ class Reline::Config
234
235
  end
235
236
  end
236
237
 
237
- def bind_variable(name, value)
238
+ def bind_variable(name, value, raw_value)
238
239
  case name
239
240
  when 'history-size'
240
241
  begin
@@ -259,7 +260,7 @@ class Reline::Config
259
260
  when 'completion-query-items'
260
261
  @completion_query_items = value.to_i
261
262
  when 'isearch-terminators'
262
- @isearch_terminators = retrieve_string(value)
263
+ @isearch_terminators = retrieve_string(raw_value)
263
264
  when 'editing-mode'
264
265
  case value
265
266
  when 'emacs'
@@ -301,11 +302,11 @@ class Reline::Config
301
302
  @show_mode_in_prompt = false
302
303
  end
303
304
  when 'vi-cmd-mode-string'
304
- @vi_cmd_mode_string = retrieve_string(value)
305
+ @vi_cmd_mode_string = retrieve_string(raw_value)
305
306
  when 'vi-ins-mode-string'
306
- @vi_ins_mode_string = retrieve_string(value)
307
+ @vi_ins_mode_string = retrieve_string(raw_value)
307
308
  when 'emacs-mode-string'
308
- @emacs_mode_string = retrieve_string(value)
309
+ @emacs_mode_string = retrieve_string(raw_value)
309
310
  when *VARIABLE_NAMES then
310
311
  variable_name = :"@#{name.tr(?-, ?_)}"
311
312
  instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')
@@ -63,7 +63,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
63
63
  # 30 ^^
64
64
  :ed_unassigned,
65
65
  # 31 ^_
66
- :ed_unassigned,
66
+ :undo,
67
67
  # 32 SPACE
68
68
  :ed_insert,
69
69
  # 33 !
@@ -319,7 +319,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
319
319
  # 158 M-^^
320
320
  :ed_unassigned,
321
321
  # 159 M-^_
322
- :ed_unassigned,
322
+ :redo,
323
323
  # 160 M-SPACE
324
324
  :em_set_mark,
325
325
  # 161 M-!
@@ -4,7 +4,6 @@ require 'reline/unicode'
4
4
  require 'tempfile'
5
5
 
6
6
  class Reline::LineEditor
7
- # TODO: undo
8
7
  # TODO: Use "private alias_method" idiom after drop Ruby 2.5.
9
8
  attr_reader :byte_pointer
10
9
  attr_accessor :confirm_multiline_termination_proc
@@ -75,7 +74,7 @@ class Reline::LineEditor
75
74
  def initialize(config, encoding)
76
75
  @config = config
77
76
  @completion_append_character = ''
78
- @screen_size = Reline::IOGate.get_screen_size
77
+ @screen_size = [0, 0] # Should be initialized with actual winsize in LineEditor#reset
79
78
  reset_variables(encoding: encoding)
80
79
  end
81
80
 
@@ -251,6 +250,9 @@ class Reline::LineEditor
251
250
  @resized = false
252
251
  @cache = {}
253
252
  @rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
253
+ @input_lines = [[[""], 0, 0]]
254
+ @input_lines_position = 0
255
+ @undoing = false
254
256
  reset_line
255
257
  end
256
258
 
@@ -948,7 +950,8 @@ class Reline::LineEditor
948
950
  unless @waiting_proc
949
951
  byte_pointer_diff = @byte_pointer - old_byte_pointer
950
952
  @byte_pointer = old_byte_pointer
951
- send(@vi_waiting_operator, byte_pointer_diff)
953
+ method_obj = method(@vi_waiting_operator)
954
+ wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
952
955
  cleanup_waiting
953
956
  end
954
957
  else
@@ -1009,7 +1012,8 @@ class Reline::LineEditor
1009
1012
  if @vi_waiting_operator
1010
1013
  byte_pointer_diff = @byte_pointer - old_byte_pointer
1011
1014
  @byte_pointer = old_byte_pointer
1012
- send(@vi_waiting_operator, byte_pointer_diff)
1015
+ method_obj = method(@vi_waiting_operator)
1016
+ wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
1013
1017
  cleanup_waiting
1014
1018
  end
1015
1019
  @kill_ring.process
@@ -1106,6 +1110,7 @@ class Reline::LineEditor
1106
1110
  end
1107
1111
 
1108
1112
  def input_key(key)
1113
+ save_old_buffer
1109
1114
  @config.reset_oneshot_key_bindings
1110
1115
  @dialogs.each do |dialog|
1111
1116
  if key.char.instance_of?(Symbol) and key.char == dialog.name
@@ -1120,7 +1125,6 @@ class Reline::LineEditor
1120
1125
  finish
1121
1126
  return
1122
1127
  end
1123
- old_lines = @buffer_of_lines.dup
1124
1128
  @first_char = false
1125
1129
  @completion_occurs = false
1126
1130
 
@@ -1134,12 +1138,15 @@ class Reline::LineEditor
1134
1138
  @completion_journey_state = nil
1135
1139
  end
1136
1140
 
1141
+ push_input_lines unless @undoing
1142
+ @undoing = false
1143
+
1137
1144
  if @in_pasting
1138
1145
  clear_dialogs
1139
1146
  return
1140
1147
  end
1141
1148
 
1142
- modified = old_lines != @buffer_of_lines
1149
+ modified = @old_buffer_of_lines != @buffer_of_lines
1143
1150
  if !@completion_occurs && modified && !@config.disable_completion && @config.autocompletion
1144
1151
  # Auto complete starts only when edited
1145
1152
  process_insert(force: true)
@@ -1148,6 +1155,29 @@ class Reline::LineEditor
1148
1155
  modified
1149
1156
  end
1150
1157
 
1158
+ def save_old_buffer
1159
+ @old_buffer_of_lines = @buffer_of_lines.dup
1160
+ end
1161
+
1162
+ def push_input_lines
1163
+ if @old_buffer_of_lines == @buffer_of_lines
1164
+ @input_lines[@input_lines_position] = [@buffer_of_lines.dup, @byte_pointer, @line_index]
1165
+ else
1166
+ @input_lines = @input_lines[0..@input_lines_position]
1167
+ @input_lines_position += 1
1168
+ @input_lines.push([@buffer_of_lines.dup, @byte_pointer, @line_index])
1169
+ end
1170
+ trim_input_lines
1171
+ end
1172
+
1173
+ MAX_INPUT_LINES = 100
1174
+ def trim_input_lines
1175
+ if @input_lines.size > MAX_INPUT_LINES
1176
+ @input_lines.shift
1177
+ @input_lines_position -= 1
1178
+ end
1179
+ end
1180
+
1151
1181
  def scroll_into_view
1152
1182
  _wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
1153
1183
  if wrapped_cursor_y < screen_scroll_top
@@ -1224,6 +1254,18 @@ class Reline::LineEditor
1224
1254
  process_auto_indent
1225
1255
  end
1226
1256
 
1257
+ def set_current_lines(lines, byte_pointer = nil, line_index = 0)
1258
+ cursor = current_byte_pointer_cursor
1259
+ @buffer_of_lines = lines
1260
+ @line_index = line_index
1261
+ if byte_pointer
1262
+ @byte_pointer = byte_pointer
1263
+ else
1264
+ calculate_nearest_cursor(cursor)
1265
+ end
1266
+ process_auto_indent
1267
+ end
1268
+
1227
1269
  def retrieve_completion_block(set_completion_quote_character = false)
1228
1270
  if Reline.completer_word_break_characters.empty?
1229
1271
  word_break_regexp = nil
@@ -1306,6 +1348,7 @@ class Reline::LineEditor
1306
1348
  end
1307
1349
 
1308
1350
  def insert_pasted_text(text)
1351
+ save_old_buffer
1309
1352
  pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
1310
1353
  post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
1311
1354
  lines = (pre + text.gsub(/\r\n?/, "\n") + post).split("\n", -1)
@@ -1313,6 +1356,7 @@ class Reline::LineEditor
1313
1356
  @buffer_of_lines[@line_index, 1] = lines
1314
1357
  @line_index += lines.size - 1
1315
1358
  @byte_pointer = @buffer_of_lines[@line_index].bytesize - post.bytesize
1359
+ push_input_lines
1316
1360
  end
1317
1361
 
1318
1362
  def insert_text(text)
@@ -2487,4 +2531,24 @@ class Reline::LineEditor
2487
2531
  private def vi_editing_mode(key)
2488
2532
  @config.editing_mode = :vi_insert
2489
2533
  end
2534
+
2535
+ private def undo(_key)
2536
+ @undoing = true
2537
+
2538
+ return if @input_lines_position <= 0
2539
+
2540
+ @input_lines_position -= 1
2541
+ target_lines, target_cursor_x, target_cursor_y = @input_lines[@input_lines_position]
2542
+ set_current_lines(target_lines.dup, target_cursor_x, target_cursor_y)
2543
+ end
2544
+
2545
+ private def redo(_key)
2546
+ @undoing = true
2547
+
2548
+ return if @input_lines_position >= @input_lines.size - 1
2549
+
2550
+ @input_lines_position += 1
2551
+ target_lines, target_cursor_x, target_cursor_y = @input_lines[@input_lines_position]
2552
+ set_current_lines(target_lines.dup, target_cursor_x, target_cursor_y)
2553
+ end
2490
2554
  end
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.5.6'
2
+ VERSION = '0.5.8'
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.5.6
4
+ version: 0.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-09 00:00:00.000000000 Z
11
+ date: 2024-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console