Still some open questions, but this is starting to seem usable.
I'm not ready to start writing tests yet. The manual tests so far are just preliminary statements of potential desires that may not be contradictory.
MO4B3HJQL7KU2CETG74EV367YPREQN3Z5DJP2MNHITVW2KQRXRCAC
VSBSWTE4IVQDRXLPQ7VTDIIEBEF7GMGRBHZ2IA73ZR6B2KZWI5JAC
R6L4RDWKYF7FOWXYKVRCX76GHVH74OQ6AAIZK3YLWDTDQ723FUOAC
CSSNHSKE7W2VYWLPXDUQF5WQ5KPX3SWJIQ5TQS6CYDXZHUTTYJRQC
J3ER7DFO2TXYUMJAXZUFEHQNLFDNIXSYDTE7HEFGQ2RYB3A6RFPAC
OTIBCAUJ3KDQJLVDN3A536DLZGNRYMGJLORZVR3WLCGXGO6UGO6AC
VIU2FBNVHG5FV5AJLVPMGEUO5HCLJEGZTRWNY2C5XC4AKMQZZKVAC
HCLCAFHPRUDGNFOYXKNHME2ELQKSXUTN3E4NV3PT4DGG2VJV7KOAC
X22MOJHFLXMZQJN4IP2HAXIIVD2ALPR4EO5V5YDYF6QPXS7ZNB6QC
S4U35JJQWC3CBNKHAEZ2DYEGUT5L3UYVAO6PJ5R7HSTD53KWVAXQC
NGCYNQEAAROJCQKUJDLGZALNYAU5MTNTGW4XBG6MGAHSHFG6PPMAC
5XQ4Y7NU63X2WW4ZR4P46LX5GEOTE7JH3AUMTDQW5VZ53GELNP2QC
BJ5X5O4ACBBJ56LRBBSTCW6IBQP4HAEOOOPNH3SKTA4F66YTOIDAC
-- - the editor operates entirely in viewport-relative coordinates; 0,0 is the top-left corner of the window. However the note-taking app in read-only mode largely operates in absolute coordinates; a potentially large 2D space that the window is just a peephole into.
-- - the editor operates entirely in viewport-relative coordinates; 0,0 is
-- the top-left corner of the window. However the note-taking app in
-- read-only mode largely operates in absolute coordinates; a potentially
-- large 2D space that the window is just a peephole into.
-- there are multiple columns
-- each column contains panes
-- each pane refers to a pane id, either a file name or in-memory data and contains most editor state (not the actual contents; we don't want to duplicate that if we have duplicate panes on the surface)
-- - there are multiple columns
-- - each column contains panes
-- - each pane refers to a pane id, either a file name or in-memory data and
-- contains most editor state (not the actual contents; we don't want to
-- duplicate that if we have duplicate panes on the surface)
-- Since the editor deals with potentially changing data, it tries to maintain
-- just a screen's worth of screen-line data.
-- Since the larger note-taking app mostly deals with read-only data, it
-- maintains screen-line data for the entirety of each file.
-- To map between the two we have the following timeline of events:
-- - a keystroke that scrolls the editor modifies pane.screen_top1
-- - we update Display_settings.y to scroll all neighboring panes as well
-- - App.draw uses Display_settings.y to set pane.top and renders everything
-- from pane.top to bottom of screen
-- - if pane.top is extremely negative this can involve a lot of work, so we...
print(('%d,%d: adjusting pane top %d; screen_top is at line %d (max %d)'):format(column_index, pane_index, pane.top, pane.screen_top1.line, #pane.lines))
--? print(('%d,%d: adjusting pane top %d; screen_top is at line %d (max %d)'):format(column_index, pane_index, pane.top, pane.screen_top1.line, #pane.lines))
print(('pane top is now %d'):format(pane.top))
--? print(('pane top is %d'):format(pane.top))
if pane.show_cursor and not eq(pane.screen_top1, {line=1, pos=1}) then
pane.top = math.max(Margin_top, pane.top)
--? print(('tweaking pane top to %d'):format(pane.top))
end
-- y coordinate of screen_top if a pane is editable
function sy_of_screen_top_in_cursor_pane()
local pane = Surface[Cursor_pane.col][Cursor_pane.row]
local result = up_edge_sy(Cursor_pane.col, Cursor_pane.row)
--? print(('updating viewport y; cursor pane starts at %d; screen top is at %d,%d'):format(result, pane.screen_top1.line, pane.screen_top1.pos))
if pane.screen_top1.line == 1 and pane.screen_top1.pos == 1 then
--? print('', 'b')
return result
end
--? print('c')
for i=1,pane.screen_top1.line-1 do
--? print('', 'd', i, result)
Text.populate_screen_line_starting_pos(pane, i)
result = result + line_height(pane, i, pane.left, pane.right)
end
--? print(('viewport at %d'):format(result))
return result
end
function screen_top_of_y_in_cursor_pane()
end
function line_height(State, line_index, left, right)
local line = State.lines[line_index]
local line_cache = State.line_cache[line_index]
if line.mode == 'text' then
return Line_height*#line_cache.screen_line_starting_pos
else
return Drawing.pixels(line.h, right-left) + Drawing_padding_height
end
end
* Mouse click within pane can select text
* A single pane is colored distinctly and called the cursor pane
* Hitting ctrl+x toggles edit mode for the cursor pane
* There can never be more than one pane in edit mode
* Moving arrow keys and shift-arrow keys and pageup/pagedown normally pans surface around while keeping cursor on screen
* Exception: When cursor pane is in edit mode, keys move the cursor as in lines.love
* Scrolling within a cursor pane larger than screen height in edit mode also pans the surface around
* Trying to scroll past edge of cursor pane in edit mode doesn't move the surface
* Mouse click outside pane can pan surface around
* Cursor pane never changes
* The pane in edit mode might go off screen
* Cursor in pane in edit mode might go off screen
* Perhaps keys should not go to cursor pane if it's off screen (or cursor is off screen in edit mode)? Then you only get global keys?
* lines.love assumes cursor can never be above screen top. Do we want to violate this constraint in pensieve? Or move the cursor to satisfy it as needed? Or forbid movements that would violate it?
* Typing into a pane in edit mode never pans the surface if cursor is visible