Implement vertical cursor movement and reset cursor on file open
This commit is contained in:
parent
d33e68ab2c
commit
3f53836ade
|
|
@ -167,6 +167,7 @@ func GoToEditor(data any) {
|
||||||
// data is the filename string from the browser list.
|
// data is the filename string from the browser list.
|
||||||
func OpenFile(data any) {
|
func OpenFile(data any) {
|
||||||
TheState.Editor.Buffer = "Select a file to edit..." // Placeholder, should be loaded from file
|
TheState.Editor.Buffer = "Select a file to edit..." // Placeholder, should be loaded from file
|
||||||
|
TheState.Editor.CursorPosition = 0 // Reset cursor to top
|
||||||
TheState.ScrollOffset = 0 // Reset editor scroll to top when opening a new file
|
TheState.ScrollOffset = 0 // Reset editor scroll to top when opening a new file
|
||||||
TheState.page = EditorPage
|
TheState.page = EditorPage
|
||||||
TheState.FocusedElementID = "editor_text" // Set focus to editor
|
TheState.FocusedElementID = "editor_text" // Set focus to editor
|
||||||
|
|
@ -214,6 +215,10 @@ func HandleKeyDown(data any) {
|
||||||
HandleCursorMove(-1)
|
HandleCursorMove(-1)
|
||||||
case key.NameRightArrow:
|
case key.NameRightArrow:
|
||||||
HandleCursorMove(1)
|
HandleCursorMove(1)
|
||||||
|
case key.NameUpArrow:
|
||||||
|
HandleVerticalCursorMove(true)
|
||||||
|
case key.NameDownArrow:
|
||||||
|
HandleVerticalCursorMove(false)
|
||||||
case key.NameDeleteBackward:
|
case key.NameDeleteBackward:
|
||||||
HandleBackspace()
|
HandleBackspace()
|
||||||
case key.NameDeleteForward:
|
case key.NameDeleteForward:
|
||||||
|
|
@ -222,6 +227,91 @@ func HandleKeyDown(data any) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleVerticalCursorMove updates the cursor position to the previous or next visual line.
|
||||||
|
func HandleVerticalCursorMove(up bool) {
|
||||||
|
layout := TheState.Editor.GlyphLayout
|
||||||
|
if len(layout.ByteOffsets) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pos := TheState.Editor.CursorPosition
|
||||||
|
// Find current glyph index.
|
||||||
|
idx := sort.Search(len(layout.ByteOffsets), func(i int) bool {
|
||||||
|
return layout.ByteOffsets[i] >= pos
|
||||||
|
})
|
||||||
|
// If idx == len, we are at the end. Use the last glyph.
|
||||||
|
if idx == len(layout.ByteOffsets) {
|
||||||
|
idx = len(layout.ByteOffsets) - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
currentX := layout.X[idx]
|
||||||
|
currentY := layout.Y[idx]
|
||||||
|
|
||||||
|
var targetIdx int = idx
|
||||||
|
|
||||||
|
if up {
|
||||||
|
// Scan backwards to find the previous line's Y.
|
||||||
|
prevY := currentY
|
||||||
|
for i := idx; i >= 0; i-- {
|
||||||
|
if layout.Y[i] < prevY {
|
||||||
|
prevY = layout.Y[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if prevY == currentY {
|
||||||
|
// Already at the top line?
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now find the closest X in prevY.
|
||||||
|
bestDiff := float32(1e9)
|
||||||
|
for i := 0; i < len(layout.Y); i++ {
|
||||||
|
if layout.Y[i] == prevY {
|
||||||
|
diff := float32(layout.X[i] - currentX)
|
||||||
|
if diff < 0 {
|
||||||
|
diff = -diff
|
||||||
|
}
|
||||||
|
if diff < bestDiff {
|
||||||
|
bestDiff = diff
|
||||||
|
targetIdx = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Scan forwards to find the next line's Y.
|
||||||
|
nextY := currentY
|
||||||
|
for i := idx; i < len(layout.Y); i++ {
|
||||||
|
if layout.Y[i] > nextY {
|
||||||
|
nextY = layout.Y[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nextY == currentY {
|
||||||
|
// Already at the bottom line?
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now find the closest X in nextY.
|
||||||
|
bestDiff := float32(1e9)
|
||||||
|
for i := 0; i < len(layout.Y); i++ {
|
||||||
|
if layout.Y[i] == nextY {
|
||||||
|
diff := float32(layout.X[i] - currentX)
|
||||||
|
if diff < 0 {
|
||||||
|
diff = -diff
|
||||||
|
}
|
||||||
|
if diff < bestDiff {
|
||||||
|
bestDiff = diff
|
||||||
|
targetIdx = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TheState.Editor.CursorPosition = layout.ByteOffsets[targetIdx]
|
||||||
|
}
|
||||||
|
|
||||||
// HandleDelete removes the character after the cursor.
|
// HandleDelete removes the character after the cursor.
|
||||||
func HandleDelete() {
|
func HandleDelete() {
|
||||||
pos := TheState.Editor.CursorPosition
|
pos := TheState.Editor.CursorPosition
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user