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  }