reline 0.5.6 → 0.5.7

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: 06a566ff8fc4daaf8ecee47eb28dac9e3e1a1d94fe05be5b9b9e1eb3a58228cc
4
+ data.tar.gz: 70b3aa5a4bcbf7fd7e564d47857f18717e49e2163ee5e5789d81f0bc246a2e17
5
5
  SHA512:
6
- metadata.gz: 0031f7bd3660b7adda54149c1e15da1d1d2f9ef5c7e240828c9a1f3337d0c7bf2e1796c5ba6f61f1352c18819225697e4dd7c32149ff3297f65ddf0fd8f06e82
7
- data.tar.gz: ea8bfe21ce43dbd3f1f6fa23d1d1a1948005cdda278485bba9010060f1ad1e3900c749e1a2966caf39f892c4c38692bc4abe8283425e3c3138e273f65b170ca9
6
+ metadata.gz: e1eaf728bdb9be12e3d6fdba67a00651641426f7f70b6248360d47b7101d638d17b9ddbc70e20ad6fbd428dfcd69a6cb75e01bf4f9b20ebde16c3c5e2216231d
7
+ data.tar.gz: 28645bd429b1210b50875109c1fad90a5cd759e0411e99292ef1d785341b28ae851d144c3e1faeae994e42eaed735a71f8a94d5c74423085f1ac7d5ce72bdb72
@@ -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 !
@@ -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,8 @@ class Reline::LineEditor
251
250
  @resized = false
252
251
  @cache = {}
253
252
  @rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
253
+ @past_lines = []
254
+ @undoing = false
254
255
  reset_line
255
256
  end
256
257
 
@@ -948,7 +949,8 @@ class Reline::LineEditor
948
949
  unless @waiting_proc
949
950
  byte_pointer_diff = @byte_pointer - old_byte_pointer
950
951
  @byte_pointer = old_byte_pointer
951
- send(@vi_waiting_operator, byte_pointer_diff)
952
+ method_obj = method(@vi_waiting_operator)
953
+ wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
952
954
  cleanup_waiting
953
955
  end
954
956
  else
@@ -1009,7 +1011,8 @@ class Reline::LineEditor
1009
1011
  if @vi_waiting_operator
1010
1012
  byte_pointer_diff = @byte_pointer - old_byte_pointer
1011
1013
  @byte_pointer = old_byte_pointer
1012
- send(@vi_waiting_operator, byte_pointer_diff)
1014
+ method_obj = method(@vi_waiting_operator)
1015
+ wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
1013
1016
  cleanup_waiting
1014
1017
  end
1015
1018
  @kill_ring.process
@@ -1106,6 +1109,7 @@ class Reline::LineEditor
1106
1109
  end
1107
1110
 
1108
1111
  def input_key(key)
1112
+ save_old_buffer
1109
1113
  @config.reset_oneshot_key_bindings
1110
1114
  @dialogs.each do |dialog|
1111
1115
  if key.char.instance_of?(Symbol) and key.char == dialog.name
@@ -1120,7 +1124,6 @@ class Reline::LineEditor
1120
1124
  finish
1121
1125
  return
1122
1126
  end
1123
- old_lines = @buffer_of_lines.dup
1124
1127
  @first_char = false
1125
1128
  @completion_occurs = false
1126
1129
 
@@ -1134,12 +1137,15 @@ class Reline::LineEditor
1134
1137
  @completion_journey_state = nil
1135
1138
  end
1136
1139
 
1140
+ push_past_lines unless @undoing
1141
+ @undoing = false
1142
+
1137
1143
  if @in_pasting
1138
1144
  clear_dialogs
1139
1145
  return
1140
1146
  end
1141
1147
 
1142
- modified = old_lines != @buffer_of_lines
1148
+ modified = @old_buffer_of_lines != @buffer_of_lines
1143
1149
  if !@completion_occurs && modified && !@config.disable_completion && @config.autocompletion
1144
1150
  # Auto complete starts only when edited
1145
1151
  process_insert(force: true)
@@ -1148,6 +1154,26 @@ class Reline::LineEditor
1148
1154
  modified
1149
1155
  end
1150
1156
 
1157
+ def save_old_buffer
1158
+ @old_buffer_of_lines = @buffer_of_lines.dup
1159
+ @old_byte_pointer = @byte_pointer.dup
1160
+ @old_line_index = @line_index.dup
1161
+ end
1162
+
1163
+ def push_past_lines
1164
+ if @old_buffer_of_lines != @buffer_of_lines
1165
+ @past_lines.push([@old_buffer_of_lines, @old_byte_pointer, @old_line_index])
1166
+ end
1167
+ trim_past_lines
1168
+ end
1169
+
1170
+ MAX_PAST_LINES = 100
1171
+ def trim_past_lines
1172
+ if @past_lines.size > MAX_PAST_LINES
1173
+ @past_lines.shift
1174
+ end
1175
+ end
1176
+
1151
1177
  def scroll_into_view
1152
1178
  _wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
1153
1179
  if wrapped_cursor_y < screen_scroll_top
@@ -1224,6 +1250,18 @@ class Reline::LineEditor
1224
1250
  process_auto_indent
1225
1251
  end
1226
1252
 
1253
+ def set_current_lines(lines, byte_pointer = nil, line_index = 0)
1254
+ cursor = current_byte_pointer_cursor
1255
+ @buffer_of_lines = lines
1256
+ @line_index = line_index
1257
+ if byte_pointer
1258
+ @byte_pointer = byte_pointer
1259
+ else
1260
+ calculate_nearest_cursor(cursor)
1261
+ end
1262
+ process_auto_indent
1263
+ end
1264
+
1227
1265
  def retrieve_completion_block(set_completion_quote_character = false)
1228
1266
  if Reline.completer_word_break_characters.empty?
1229
1267
  word_break_regexp = nil
@@ -1306,6 +1344,7 @@ class Reline::LineEditor
1306
1344
  end
1307
1345
 
1308
1346
  def insert_pasted_text(text)
1347
+ save_old_buffer
1309
1348
  pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
1310
1349
  post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
1311
1350
  lines = (pre + text.gsub(/\r\n?/, "\n") + post).split("\n", -1)
@@ -1313,6 +1352,7 @@ class Reline::LineEditor
1313
1352
  @buffer_of_lines[@line_index, 1] = lines
1314
1353
  @line_index += lines.size - 1
1315
1354
  @byte_pointer = @buffer_of_lines[@line_index].bytesize - post.bytesize
1355
+ push_past_lines
1316
1356
  end
1317
1357
 
1318
1358
  def insert_text(text)
@@ -2487,4 +2527,15 @@ class Reline::LineEditor
2487
2527
  private def vi_editing_mode(key)
2488
2528
  @config.editing_mode = :vi_insert
2489
2529
  end
2530
+
2531
+ private def undo(_key)
2532
+ return if @past_lines.empty?
2533
+
2534
+ @undoing = true
2535
+
2536
+ target_lines, target_cursor_x, target_cursor_y = @past_lines.last
2537
+ set_current_lines(target_lines, target_cursor_x, target_cursor_y)
2538
+
2539
+ @past_lines.pop
2540
+ end
2490
2541
  end
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.5.6'
2
+ VERSION = '0.5.7'
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.7
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-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console