From 91556a90983d234a43784f4881e271f59636ec71 Mon Sep 17 00:00:00 2001 From: Nimaoth Date: Fri, 26 Apr 2024 21:46:48 +0200 Subject: [PATCH] Fixed cursor in wrong position when at end of line with tab --- src/text/text_document.nim | 10 ++++++---- src/ui/widget_builder_text_document.nim | 14 +++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/text/text_document.nim b/src/text/text_document.nim index 4c403256..a1adbfa8 100644 --- a/src/text/text_document.nim +++ b/src/text/text_document.nim @@ -53,6 +53,8 @@ type StyledText* = object inlayContainCursor*: bool scopeIsToken*: bool = true canWrap*: bool = true + modifyCursorAtEndOfLine*: bool = false ## If true and the cursor is at the end of the line + ## then the cursor will be behind the part. type StyledLine* = ref object index*: int @@ -479,12 +481,12 @@ proc overrideUnderline*(self: TextDocument, line: var StyledLine, first: int, la proc overrideStyleAndText*(self: TextDocument, line: var StyledLine, first: int, text: string, scope: string, priority: int, opacity: Option[float] = float.none, joinNext: bool = false) = line.overrideStyleAndText(self.lines[line.index].toOpenArray.runeIndex(first, returnLen=true), text, scope, priority, opacity, joinNext) -proc insertText*(self: TextDocument, line: var StyledLine, offset: RuneIndex, text: string, scope: string, containCursor: bool) = +proc insertText*(self: TextDocument, line: var StyledLine, offset: RuneIndex, text: string, scope: string, containCursor: bool, modifyCursorAtEndOfLine: bool = false) = line.splitAt(offset) for i in 0..line.parts.high: if line.parts[i].textRange.getSome(r): if offset == r.endIndex: - line.parts.insert(StyledText(text: text, scope: scope, scopeC: scope.cstring, priority: 1000000000, inlayContainCursor: containCursor), i + 1) + line.parts.insert(StyledText(text: text, scope: scope, scopeC: scope.cstring, priority: 1000000000, inlayContainCursor: containCursor, modifyCursorAtEndOfLine: modifyCursorAtEndOfLine), i + 1) return proc insertTextBefore*(self: TextDocument, line: var StyledLine, offset: RuneIndex, text: string, scope: string) = @@ -546,7 +548,7 @@ proc replaceTabs(self: TextDocument, line: var StyledLine) = let runeIndex = self.lines[line.index].toOpenArray.runeIndex(s.first.column, returnLen=true) line.overrideStyleAndText(runeIndex, t, "comment", 0, opacity=opacity.some) if currentTabWidth > 1: - self.insertText(line, runeIndex + 1.RuneCount, " ".repeat(currentTabWidth - 1), "comment", containCursor=false) + self.insertText(line, runeIndex + 1.RuneCount, " ".repeat(currentTabWidth - 1), "comment", containCursor=false, modifyCursorAtEndOfLine=true) currentOffset += currentTabWidth previousEnd = s.last.column @@ -1099,7 +1101,7 @@ proc moveCursorColumn(self: TextDocument, cursor: Cursor, offset: int, wrap: boo proc firstNonWhitespace*(str: string): int = result = 0 for c in str: - if c != ' ': + if c != ' ' and c != '\t': break result += 1 diff --git a/src/ui/widget_builder_text_document.nim b/src/ui/widget_builder_text_document.nim index 29da2501..f590a7ef 100644 --- a/src/ui/widget_builder_text_document.nim +++ b/src/ui/widget_builder_text_document.nim @@ -243,8 +243,8 @@ proc renderLine*( builder.panel(flagsInner + LayoutVertical + FillBackground, y = options.y, pivot = options.pivot, backgroundColor = options.backgroundColor, userId = newSecondaryId(options.parentId, options.lineId)): let lineWidth = currentNode.bounds.w - var lastNonInlaySubLine: UINode = nil - var lastNonInlayPartXW: float32 = 0 + var cursorBaseNode: UINode = nil + var cursorBaseXW: float32 = 0 var lastTextSubLine: UINode = nil var lastTextPartXW: float32 = 0 @@ -301,9 +301,9 @@ proc renderLine*( let (startRune, _) = line.getTextRange(partIndex) let partNode = renderLinePart(builder, line, backgroundColors, options, partIndex, startRune, partRuneLen) - if part.textRange.isSome: - lastNonInlaySubLine = subLine - lastNonInlayPartXW = partNode.bounds.xw + if part.textRange.isSome or part.modifyCursorAtEndOfLine: + cursorBaseNode = subLine + cursorBaseXW = partNode.bounds.xw # cursor for curs in cursors: @@ -361,11 +361,11 @@ proc renderLine*( # cursor after latest char for curs in cursors: if curs == lineOriginal.len: - result.cursors.add (lastNonInlaySubLine, "", rect(lastNonInlayPartXW, 0, builder.charWidth, builder.textHeight), (line.index, curs)) + result.cursors.add (cursorBaseNode, "", rect(cursorBaseXW, 0, builder.charWidth, builder.textHeight), (line.index, curs)) # set hover info if the hover location is at the end of this line if line.index == options.hoverLocation.line and options.hoverLocation.column == lineOriginal.len: - result.hover = (lastNonInlaySubLine, "", rect(lastNonInlayPartXW, 0, builder.charWidth, builder.textHeight), options.hoverLocation).some + result.hover = (cursorBaseNode, "", rect(cursorBaseXW, 0, builder.charWidth, builder.textHeight), options.hoverLocation).some proc blendColorRanges(colors: var seq[tuple[first: RuneIndex, last: RuneIndex, color: Color]], ranges: var seq[tuple[first: RuneIndex, last: RuneIndex]], color: Color, inclusive: bool) = let inclusiveOffset = if inclusive: 1.RuneCount else: 0.RuneCount