about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2022-06-20 11:25:00 -0700
committerKartik K. Agaram <vc@akkartik.com>2022-06-20 11:31:14 -0700
commit3986e99fe0586e35a0c649114a07e6dd90f769fc (patch)
tree240a7e744e8566905d28dd93ad123f4e9db073d3
parent3be413602a59ed735a33712380cedbdb8f5603df (diff)
downloadview.love-3986e99fe0586e35a0c649114a07e6dd90f769fc.tar.gz
no, that's not right
Bugfix: we want selections to persist even when we lift up the shift
key.

This requires hoisting some code inside every case inside the whole
keypress hierarchy, to ensure we never clear selections before
textinput events can handle them.

Current cross-cutting concerns we're explicitly scattering code for.
  - autosave
  - undo
  - selection management
-rw-r--r--main.lua15
-rw-r--r--text.lua6
-rw-r--r--text_tests.lua22
3 files changed, 40 insertions, 3 deletions
diff --git a/main.lua b/main.lua
index df68da5..d4fd32a 100644
--- a/main.lua
+++ b/main.lua
@@ -407,6 +407,9 @@ function App.textinput(t)
     Text.textinput(t)
   end
   schedule_save()
+  if not App.shift_down() then
+    Selection1 = {}
+  end
 end
 
 function App.keychord_pressed(chord)
@@ -438,15 +441,19 @@ function App.keychord_pressed(chord)
     Search_term = ''
     Search_backup = {cursor={line=Cursor1.line, pos=Cursor1.pos}, screen_top={line=Screen_top1.line, pos=Screen_top1.pos}}
     assert(Search_text == nil)
+    Selection1 = {}
   elseif chord == 'C-=' then
     initialize_font_settings(Font_height+2)
     Text.redraw_all()
+    Selection1 = {}
   elseif chord == 'C--' then
     initialize_font_settings(Font_height-2)
     Text.redraw_all()
+    Selection1 = {}
   elseif chord == 'C-0' then
     initialize_font_settings(20)
     Text.redraw_all()
+    Selection1 = {}
   elseif chord == 'C-z' then
     for _,line in ipairs(Lines) do line.y = nil end  -- just in case we scroll
     local event = undo_event()
@@ -459,6 +466,7 @@ function App.keychord_pressed(chord)
       Text.redraw_all()  -- if we're scrolling, reclaim all fragments to avoid memory leaks
       schedule_save()
     end
+    Selection1 = {}
   elseif chord == 'C-y' then
     for _,line in ipairs(Lines) do line.y = nil end  -- just in case we scroll
     local event = redo_event()
@@ -471,6 +479,7 @@ function App.keychord_pressed(chord)
       Text.redraw_all()  -- if we're scrolling, reclaim all fragments to avoid memory leaks
       schedule_save()
     end
+    Selection1 = {}
   -- clipboard
   elseif chord == 'C-c' then
     for _,line in ipairs(Lines) do line.y = nil end  -- just in case we scroll
@@ -478,6 +487,7 @@ function App.keychord_pressed(chord)
     if s then
       App.setClipboardText(s)
     end
+    Selection1 = {}
   elseif chord == 'C-x' then
     for _,line in ipairs(Lines) do line.y = nil end  -- just in case we scroll
     local s = Text.cut_selection()
@@ -485,6 +495,7 @@ function App.keychord_pressed(chord)
       App.setClipboardText(s)
     end
     schedule_save()
+    Selection1 = {}
   elseif chord == 'C-v' then
     for _,line in ipairs(Lines) do line.y = nil end  -- just in case we scroll
     -- We don't have a good sense of when to scroll, so we'll be conservative
@@ -506,6 +517,7 @@ function App.keychord_pressed(chord)
     end
     schedule_save()
     record_undo_event({before=before, after=snapshot(before_line, Cursor1.line)})
+    Selection1 = {}
   -- dispatch to drawing or text
   elseif App.mouse_down(1) or chord:sub(1,2) == 'C-' then
     -- DON'T reset line.y here
@@ -553,7 +565,4 @@ function App.keychord_pressed(chord)
 end
 
 function App.keyreleased(key, scancode)
-  if not App.shift_down() then
-    Selection1 = {}
-  end
 end
diff --git a/text.lua b/text.lua
index f7f2e80..2888c1f 100644
--- a/text.lua
+++ b/text.lua
@@ -175,6 +175,7 @@ function Text.keychord_pressed(chord)
     end
     schedule_save()
     record_undo_event({before=before, after=snapshot(before_line, Cursor1.line)})
+    Selection1 = {}
   elseif chord == 'tab' then
     local before = snapshot(Cursor1.line)
 --?     print(Screen_top1.line, Screen_top1.pos, Cursor1.line, Cursor1.pos, Screen_bottom1.line, Screen_bottom1.pos)
@@ -186,10 +187,12 @@ function Text.keychord_pressed(chord)
     end
     schedule_save()
     record_undo_event({before=before, after=snapshot(Cursor1.line)})
+    Selection1 = {}
   elseif chord == 'backspace' then
     if Selection1.line then
       Text.delete_selection()
       schedule_save()
+      Selection1 = {}
       return
     end
     local before
@@ -228,10 +231,12 @@ function Text.keychord_pressed(chord)
     assert(Text.le1(Screen_top1, Cursor1))
     schedule_save()
     record_undo_event({before=before, after=snapshot(Cursor1.line)})
+    Selection1 = {}
   elseif chord == 'delete' then
     if Selection1.line then
       Text.delete_selection()
       schedule_save()
+      Selection1 = {}
       return
     end
     local before
@@ -264,6 +269,7 @@ function Text.keychord_pressed(chord)
     end
     schedule_save()
     record_undo_event({before=before, after=snapshot(Cursor1.line)})
+    Selection1 = {}
   --== shortcuts that move the cursor
   elseif chord == 'left' then
     if Selection1.line then
diff --git a/text_tests.lua b/text_tests.lua
index 95fbd78..7c0ce7d 100644
--- a/text_tests.lua
+++ b/text_tests.lua
@@ -186,6 +186,28 @@ function test_click_on_wrapping_line_containing_non_ascii()
   check_eq(Cursor1.pos, 15, 'F - test_click_on_wrapping_line_containing_non_ascii/cursor')  -- one more than the number of UTF-8 code-points
 end
 
+function test_select_text()
+  io.write('\ntest_select_text')
+  -- display a line of text
+  App.screen.init{width=80, height=80}
+  Lines = load_array{'abc def'}
+  Line_width = 75
+  Cursor1 = {line=1, pos=1}
+  Screen_top1 = {line=1, pos=1}
+  Screen_bottom1 = {}
+  App.draw()
+  -- select a letter
+  App.fake_key_press('lshift')
+  App.run_after_keychord('S-right')
+  App.fake_key_release('lshift')
+  App.keyreleased('lshift')
+  -- selection persists even after shift is released
+  check_eq(Selection1.line, 1, 'F - test_select_text/selection:line')
+  check_eq(Selection1.pos, 1, 'F - test_select_text/selection:pos')
+  check_eq(Cursor1.line, 1, 'F - test_select_text/cursor:line')
+  check_eq(Cursor1.pos, 2, 'F - test_select_text/cursor:pos')
+end
+
 function test_edit_after_click_resets_selection()
   io.write('\ntest_edit_after_click_resets_selection')
   -- display a line of text