core icon indicating copy to clipboard operation
core copied to clipboard

New Text Editor Word Wrap Breaks Line Alignment

Open MongooseStudios opened this issue 7 months ago • 1 comments

Describe the bug

Using the new textcore.TextEditor, when entering input longer than a line, word wrapping causes the line to fall down below its line number.

Edit: Also, if you are deleting a line after a word wrapped line, as soon as that new line becomes empty the next backspace will cause a panic (see output)

Lastly, if you are trying to delete an empty line right below a line with text, the line above it will disappear on the first backspace, and then re-appear on a subsequent backspace input

Note: This happens even if you do not set a styler to limit the width, it's just easier to trigger it that way, so I did it for the repro.

How to reproduce

Run example code, enter enough characters to trigger wrapping

Example code

package main

import (
	"cogentcore.org/core/core"
	"cogentcore.org/core/styles"
	"cogentcore.org/core/styles/units"
	"cogentcore.org/core/text/lines"
	"cogentcore.org/core/text/textcore"
)

func main() {
	b := core.NewBody("Text Editor Repro")

	editorLines := lines.NewLines()
	myEditor := textcore.NewEditor(b).SetLines(editorLines)
	myEditor.Styler(func(s *styles.Style) {
		s.Max.Set(units.Em(20), units.Em(5))
	})

	b.RunMainWindow()
}

Relevant output

2025/05/26 14:47:28 panic: runtime error: slice bounds out of range [:-1]
2025/05/26 14:47:28 
2025/05/26 14:47:28 ----- START OF STACK TRACE: -----
2025/05/26 14:47:28 goroutine 37 [running]:
runtime/debug.Stack()
	/usr/local/go/src/runtime/debug/stack.go:26 +0x5e
cogentcore.org/core/system.HandleRecoverBase({0x15dace0, 0xc001249458})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/system/recover.go:50 +0x4b
cogentcore.org/core/core.handleRecover({0x15dace0, 0xc001249458})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/recover.go:39 +0x52
cogentcore.org/core/core.(*renderWindow).eventLoop.func1()
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/renderwindow.go:404 +0x24
panic({0x15dace0?, 0xc001249458?})
	/usr/local/go/src/runtime/panic.go:792 +0x132
cogentcore.org/core/text/lines.(*Lines).layoutViewLine(0xc0002c6a88, 0x0, 0x16, {0xc000110680, 0x1c, 0x20}, {0xc002036a08, 0x1, 0x4b504f?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/layout.go:133 +0xa7d
cogentcore.org/core/text/lines.(*Lines).layoutViewLines(0xc0002c6a88, 0xc0002ac0c0)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/layout.go:28 +0x22d
cogentcore.org/core/text/lines.(*Lines).layoutViews(...)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/markup.go:184
cogentcore.org/core/text/lines.(*Lines).startDelayedReMarkup(0xc0002c6a88)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/markup.go:57 +0x207
cogentcore.org/core/text/lines.(*Lines).linesDeleted(0xc0002c6a88, 0xc001c0ef00)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/markup.go:281 +0x8c9
cogentcore.org/core/text/lines.(*Lines).deleteTextImpl(0xc0002c6a88, {0x80?, 0xc00004da40?}, {0xe3851a?, 0xc0002ecd88?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/lines.go:507 +0x586
cogentcore.org/core/text/lines.(*Lines).deleteText(0xc0002c6a88, {0xc0002ecd88?, 0xc002e45630?}, {0xc00004da40?, 0xe38620?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/lines.go:468 +0x18
cogentcore.org/core/text/lines.(*Lines).DeleteText(0xc0002c6a88, {0x1?, 0xc00004da78?}, {0x0?, 0x2a?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/api.go:450 +0x87
cogentcore.org/core/text/textcore.(*Base).cursorBackspace(0xc0002ecd88, 0x1?)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/textcore/nav.go:314 +0x125
cogentcore.org/core/text/textcore.(*Editor).keyInput(0xc0002ecd88, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/textcore/editor.go:385 +0x13a5
cogentcore.org/core/text/textcore.(*Editor).Init.(*Editor).handleKeyChord.func1({0x1b72b10?, 0xc00226a620?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/textcore/editor.go:158 +0x2a
cogentcore.org/core/events.(*Listeners).Call(0xc00004dbb8, {0x1b72b10, 0xc00226a620}, {0xc00004dc28, 0x1, 0x0?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/events/listeners.go:61 +0xf9
cogentcore.org/core/core.(*WidgetBase).HandleEvent.func1(...)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/widgetevents.go:252
cogentcore.org/core/base/tiered.(*Tiered[...]).Do(...)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/base/tiered/tiered.go:30
cogentcore.org/core/core.(*WidgetBase).HandleEvent(0xc0002ecd88, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/widgetevents.go:251 +0x1f9
cogentcore.org/core/core.(*Events).handleFocusEvent(0xc0001e3b88, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/events.go:207 +0x245
cogentcore.org/core/core.(*Events).handleEvent(0xc0001e3b88, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/events.go:176 +0x85
cogentcore.org/core/core.(*Stage).mainHandleEvent(0xc0002a2a90, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/mainstage.go:433 +0x185
cogentcore.org/core/core.(*stages).mainHandleEvent(0xc000279890, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/mainstage.go:441 +0x73
cogentcore.org/core/core.(*renderWindow).handleEvent(0xc000279860, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/renderwindow.go:459 +0x44b
cogentcore.org/core/core.(*renderWindow).eventLoop(0xc000279860)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/renderwindow.go:418 +0xc5
created by cogentcore.org/core/core.(*renderWindow).goStartEventLoop in goroutine 1
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/renderwindow.go:389 +0x65

2025/05/26 14:47:28 ----- END OF STACK TRACE -----
2025/05/26 14:47:28 SAVED CRASH LOG TO /home/dappermongoose/.config/Text\ Editor\ Repro/crash-logs/crash_2025-05-26_14-47-28
panic: runtime error: slice bounds out of range [:-1] [recovered]
	panic: runtime error: slice bounds out of range [:-1]

goroutine 37 [running]:
cogentcore.org/core/core.handleRecover({0x15dace0, 0xc001249458})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/recover.go:87 +0x47b
cogentcore.org/core/core.(*renderWindow).eventLoop.func1()
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/renderwindow.go:404 +0x24
panic({0x15dace0?, 0xc001249458?})
	/usr/local/go/src/runtime/panic.go:792 +0x132
cogentcore.org/core/text/lines.(*Lines).layoutViewLine(0xc0002c6a88, 0x0, 0x16, {0xc000110680, 0x1c, 0x20}, {0xc002036a08, 0x1, 0x4b504f?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/layout.go:133 +0xa7d
cogentcore.org/core/text/lines.(*Lines).layoutViewLines(0xc0002c6a88, 0xc0002ac0c0)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/layout.go:28 +0x22d
cogentcore.org/core/text/lines.(*Lines).layoutViews(...)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/markup.go:184
cogentcore.org/core/text/lines.(*Lines).startDelayedReMarkup(0xc0002c6a88)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/markup.go:57 +0x207
cogentcore.org/core/text/lines.(*Lines).linesDeleted(0xc0002c6a88, 0xc001c0ef00)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/markup.go:281 +0x8c9
cogentcore.org/core/text/lines.(*Lines).deleteTextImpl(0xc0002c6a88, {0x80?, 0xc00004da40?}, {0xe3851a?, 0xc0002ecd88?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/lines.go:507 +0x586
cogentcore.org/core/text/lines.(*Lines).deleteText(0xc0002c6a88, {0xc0002ecd88?, 0xc002e45630?}, {0xc00004da40?, 0xe38620?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/lines.go:468 +0x18
cogentcore.org/core/text/lines.(*Lines).DeleteText(0xc0002c6a88, {0x1?, 0xc00004da78?}, {0x0?, 0x2a?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/lines/api.go:450 +0x87
cogentcore.org/core/text/textcore.(*Base).cursorBackspace(0xc0002ecd88, 0x1?)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/textcore/nav.go:314 +0x125
cogentcore.org/core/text/textcore.(*Editor).keyInput(0xc0002ecd88, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/textcore/editor.go:385 +0x13a5
cogentcore.org/core/text/textcore.(*Editor).Init.(*Editor).handleKeyChord.func1({0x1b72b10?, 0xc00226a620?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/text/textcore/editor.go:158 +0x2a
cogentcore.org/core/events.(*Listeners).Call(0xc00004dbb8, {0x1b72b10, 0xc00226a620}, {0xc00004dc28, 0x1, 0x0?})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/events/listeners.go:61 +0xf9
cogentcore.org/core/core.(*WidgetBase).HandleEvent.func1(...)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/widgetevents.go:252
cogentcore.org/core/base/tiered.(*Tiered[...]).Do(...)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/base/tiered/tiered.go:30
cogentcore.org/core/core.(*WidgetBase).HandleEvent(0xc0002ecd88, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/widgetevents.go:251 +0x1f9
cogentcore.org/core/core.(*Events).handleFocusEvent(0xc0001e3b88, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/events.go:207 +0x245
cogentcore.org/core/core.(*Events).handleEvent(0xc0001e3b88, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/events.go:176 +0x85
cogentcore.org/core/core.(*Stage).mainHandleEvent(0xc0002a2a90, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/mainstage.go:433 +0x185
cogentcore.org/core/core.(*stages).mainHandleEvent(0xc000279890, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/mainstage.go:441 +0x73
cogentcore.org/core/core.(*renderWindow).handleEvent(0xc000279860, {0x1b72b10, 0xc00226a620})
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/renderwindow.go:459 +0x44b
cogentcore.org/core/core.(*renderWindow).eventLoop(0xc000279860)
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/renderwindow.go:418 +0xc5
created by cogentcore.org/core/core.(*renderWindow).goStartEventLoop in goroutine 1
	/home/dappermongoose/go/pkg/mod/cogentcore.org/[email protected]/core/renderwindow.go:389 +0x65
exit status 2

Platform

Linux

MongooseStudios avatar May 26 '25 20:05 MongooseStudios

Thank you for filing this issue. I can reproduce the bugs and we will work on fixing them soon.

kkoreilly avatar May 30 '25 19:05 kkoreilly