AJIHYPZKRIA5OAXJNIK2Y2WTATNCXTUWGBIUOL2FUK257YU34YRQC UKFGXNBHRBIXREBWAN65QXV2OWZXQ5M7LQBOEUGJOPLIR2KUPDNQC PT7ICD7ZAB4IT6K5B4LURL5LUXHSN4ML5YWCG52YFLE2IBNZ53UAC R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC JOPVPUSAMMU6RFVDQR4NJC4GNNUFB7GPKVH7OS5FKCYS5QZ53VLQC HGKCNQC5DCYQ5JFQEEBQVHHMWFOVU2BHS3UZHE5JND5IJUGLC22QC RU4HIK436ZRQJEPZXFS4FQTYVRL7BK5NWKYFGHFHZQOEOBF7M5SQC ICUW7F3XQLURK4LSNPH5E3NDEFSRHKATEUHH2UPFJTMHYR3ZJF3QC 56HRXNBB5ATVDER2Q776N74I6B4W5PWCXY4U6SNS3WDBRPJ3X3TQC BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC IM3RBHY2QI5UHLPHT4QB3YECS7CRBEFE765DDKXOW267AOQZL5QQC GYPLUBXNFEHHAYSCFNW65WADQB7ZBQTAQASGBPPER6GMDRQ35UMAC LLQC2M2IMEJBJQXZTKC3OAKG5WKHSERXKAKCYHQRUZZD6CVRIHAQC SPSW74Y5OJ54Y7VQ3SJFCJR5CYDKTR4A3TOEVZODDZLUSDDU2GZAC 6PCE7VUWEE5UVSE3ZZSQAMGUJDDHOBNO2MVD6POUWFP7UY7WOZHAC QAMVLUK22RP5RBDTDV5XVPQCSJUWDWESV4TRCUTNUM46E26BH2AQC D4B52CQ2QKG2HQKFUQOO5S2ME325DTW3PH2D7SBXCW4BPQFYG7CAC 5XMBCKJZ7YCUOOQWWZRNLXMXD3MUYC2VAF3VKA4BIEHQRPDQMUMAC 3VHUIIATPOF7FXB7NTL5MESCV5BCQACII2D7QZ4UIUCBX3CWXMMAC 2EELKVO233KIH36SRY6LHYCDGARR52V62QPGONRZIKHXGV4RSNEQC GUEB7ZG772YHNKXKBXCY7XVSJKFOWKZCWESEEMPNHYHMM7UEVRYQC F52PSTYSIIUD7UPEVLEJPVSBQU7IKVHM4GN4YASNSKFP4MRE6S6AC Q65423XUYWJ5ESAH2B63MJKJUXSTQDANPZRRMQNYTDF3YGT5HLRAC 2TQUKHBC2EB3WDBD5UL62DQYV7CV6B7OJYK7CHOEDNOZENSOG42AC 3PSFWAILGRA4OYXWS2DX7VF332AIBPYBXHEA4GIQY2XEJVD65UMAC 3BFFX2I3V7N7QJ4Z6CKICF52IRKMSLT63MMZZ34JZPFYAZELJ4EQC SNQM42QARHDYXSD5NF3O5HFRL34SFEPYV4ZIC3WJL4KYSU7MD2YAC QZUFJMD5OTAZGSUO4HSJ2NNNRJR7NOKIVOIIGHWM6IF4PFNMQZHAC KCDRLLAAANY5USQHWZ5QQDZDHJFJB6NS4WYZB3WE4AW4LPIV2RAAC ETOIYTWWNT52AVFPWXDRUAEM3LQKTMIC6KJLAVMWYZLOHMZW2LSAC FXI74QCLOZ4BS7UVZ3U2PE3LOL7MX3FWGHZCTGH3DYFXGTXVVIRAC SPXS2WOLSSEEGOY5XJOITKPBL6MSD7NSXC4ESFVKP63PEFTEP33AC 4TOADL2SFUZYNP3ZO3AIBN66QAWZDL5XIZZEA3DLYRF6SSEGLF3AC OTIBCAUJ3KDQJLVDN3A536DLZGNRYMGJLORZVR3WLCGXGO6UGO6AC YGCT2D2ORMLTBHANLGHZV3EBGGHD7ZK55UAM7HF2AVSHDXAAKK5QC MX7YD2WCLJSLML3DSDVU3YLTALIVPTM7H7LNGSHEEUPOJGQHWUAAC 2CTN2IEF4ZCVZQORAEBXAUDANF6NYZA24GQ5PXK2WUDWYU5UV25QC R2ASHK5CEE3PTRLS37GP4PXJ7HIGJ6UD72KKBI57UDJI7VRROQGQC 2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC RXMHAZ6VL4EJMYEZM32G4W54EPF3BPWPIGASJ7ND45FJ5F6TJCZAC FBBHEUQNDHGZQES6GC3VW55DXILRP7PYYXNLQF3HGHKYLUGWAUBQC CQVWNL4MQYXJVKECYVKSUMRXYMQVEMYUBHHDTDMEU5GOZ67M7QOAC QMRQL2FOIIXU3PCSH7UQIDRLKJN2DQHB5IUL4TLBVANNHWWETL6AC MBAJPTDJ4KHWACEHWYGCFMHPQYM6FQKCSIIDKWCE765UI3VTDMIAC CRBLAWBOTECOU5MFURWCRBR43OO7NWIHP5LC35IMGTQKN73AUS6AC if OS == 'Linux' then-- love.window.setPosition doesn't quite seem to do what is asked of it on Linux.App.screen.move(settings.x, settings.y-37, settings.displayindex)elseApp.screen.move(settings.x, settings.y, settings.displayindex)
local dm = App.default_modifierchord ~= dm('a') and chord ~= dm('c') and chord ~= dm('x') and chord ~= 'backspace' and chord ~= 'delete' and chord ~= dm('z') and chord ~= dm('y') and not App.is_cursor_movement(key) thenelseif chord == dm('f') then
chord ~= 'C-a' and chord ~= 'C-c' and chord ~= 'C-x' and chord ~= 'backspace' and chord ~= 'delete' and chord ~= 'C-z' and chord ~= 'C-y' and not App.is_cursor_movement(key) then
chord ~= dm('a') and chord ~= dm('c') and chord ~= dm('x') and chord ~= 'backspace' and chord ~= 'delete' and chord ~= dm('z') and chord ~= dm('y') and not App.is_cursor_movement(key) then
elseif chord == dm('=') thenelseif chord == dm('-') thenelseif chord == dm('0') thenelseif chord == dm('z') then
elseif chord == dm('a') thenelseif chord == dm('c') thenelseif chord == dm('x') thenelseif chord == dm('v') then
local event = undo_event(State)if event thenlocal src = event.beforeState.screen_top1 = deepcopy(src.screen_top)State.cursor1 = deepcopy(src.cursor)State.selection1 = deepcopy(src.selection)patch(State.lines, event.after, event.before)
local event = redo_event(State)if event thenlocal src = event.afterState.screen_top1 = deepcopy(src.screen_top)State.cursor1 = deepcopy(src.cursor)State.selection1 = deepcopy(src.selection)patch(State.lines, event.before, event.after)
-- We don't have a good sense of when to scroll, so we'll be conservative-- and sometimes scroll when we didn't quite need to.local before_line = State.cursor1.linelocal before = snapshot(State, before_line)local clipboard_data = App.get_clipboard()for _,code in utf8.codes(clipboard_data) dolocal c = utf8.char(code)if c == '\n' thenText.insert_return(State)elseText.insert_at_cursor(State, c)endendif Text.cursor_out_of_screen(State) thenText.snap_cursor_to_bottom_of_screen(State, State.left, State.right)endrecord_undo_event(State, {before=before, after=snapshot(State, before_line, State.cursor1.line)})
State.line_height = math.floor(font_height*1.3)end--== some methods for tests-- Insulate tests from some key globals so I don't have to change the vast-- majority of tests when they're modified for the real app.Test_margin_left = 25Test_margin_right = 0function edit.initialize_test_state()-- if you change these values, tests will start failingreturn edit.initialize_state(15, -- top marginTest_margin_left,App.screen.width - Test_margin_right,
15) -- line heightend-- all text_input events are also keypresses-- TODO: handle chords of multiple keysfunction edit.run_after_text_input(State, t)edit.keychord_press(State, t)edit.text_input(State, t)edit.key_release(State, t)App.screen.contents = {}edit.update(State, 0)edit.draw(State)end-- not all keys are text_input
App.screen.contents = {}edit.update(State, 0)edit.draw(State)endfunction edit.run_after_mouse_click(State, x,y, mouse_button)App.fake_mouse_press(x,y, mouse_button)edit.mouse_press(State, x,y, mouse_button)
App.fake_mouse_release(x,y, mouse_button)edit.mouse_release(State, x,y, mouse_button)App.screen.contents = {}edit.update(State, 0)edit.draw(State)endfunction edit.run_after_mouse_press(State, x,y, mouse_button)App.fake_mouse_press(x,y, mouse_button)edit.mouse_press(State, x,y, mouse_button)App.screen.contents = {}edit.update(State, 0)edit.draw(State)endfunction edit.run_after_mouse_release(State, x,y, mouse_button)App.fake_mouse_release(x,y, mouse_button)edit.mouse_release(State, x,y, mouse_button)App.screen.contents = {}edit.update(State, 0)edit.draw(State)end