github.com/aretext/aretext@v1.3.0/state/view.go (about) 1 package state 2 3 import ( 4 "github.com/aretext/aretext/locate" 5 ) 6 7 // Scroll direction represents the direction of the scroll (forward or backward). 8 type ScrollDirection int 9 10 const ( 11 ScrollDirectionForward = iota 12 ScrollDirectionBackward 13 ) 14 15 // ResizeView resizes the view to the specified width and height. 16 func ResizeView(state *EditorState, width, height uint64) { 17 state.screenWidth = width 18 state.screenHeight = height 19 state.documentBuffer.view.x = 0 20 state.documentBuffer.view.y = 0 21 state.documentBuffer.view.width = state.screenWidth 22 state.documentBuffer.view.height = 0 23 if height > 0 { 24 // Leave one line for the status bar at the bottom. 25 state.documentBuffer.view.height = height - 1 26 } 27 } 28 29 // ScrollViewToCursor moves the view origin so that the cursor is visible. 30 func ScrollViewToCursor(state *EditorState) { 31 buffer := state.documentBuffer 32 scrollViewToPosition(buffer, buffer.cursor.position) 33 } 34 35 func scrollViewToPosition(buffer *BufferState, pos uint64) { 36 buffer.view.textOrigin = locate.ViewOriginAfterScroll( 37 pos, 38 buffer.textTree, 39 buffer.LineWrapConfig(), 40 buffer.view.textOrigin, 41 buffer.view.height) 42 } 43 44 // ScrollViewByNumLines moves the view origin up or down by the specified number of lines. 45 func ScrollViewByNumLines(state *EditorState, direction ScrollDirection, numLines uint64) { 46 buffer := state.documentBuffer 47 lineNum := buffer.textTree.LineNumForPosition(buffer.view.textOrigin) 48 if direction == ScrollDirectionForward { 49 lineNum += numLines 50 } else if lineNum >= numLines { 51 lineNum -= numLines 52 } else { 53 lineNum = 0 54 } 55 56 lineNum = locate.ClosestValidLineNum(buffer.textTree, lineNum) 57 58 // When scrolling to the end of the file, we want most of the last lines to remain visible. 59 // To achieve this, set the view origin (viewHeight - scrollMargin) lines above 60 // the last line. This will leave a few blank lines past the end of the document 61 // (the scroll margin) for consistency with ScrollToCursor. 62 lastLineNum := locate.ClosestValidLineNum(buffer.textTree, buffer.textTree.NumLines()) 63 if lastLineNum-lineNum < buffer.view.height { 64 if lastLineNum+locate.ScrollMargin+1 > buffer.view.height { 65 lineNum = lastLineNum + locate.ScrollMargin + 1 - buffer.view.height 66 } else { 67 lineNum = 0 68 } 69 } 70 71 buffer.view.textOrigin = buffer.textTree.LineStartPosition(lineNum) 72 }