diff options
author | bptato <nincsnevem662@gmail.com> | 2024-09-28 17:29:12 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-09-28 17:54:08 +0200 |
commit | 9c257361388f5007871a36eea3abc815a8740d66 (patch) | |
tree | 3c9494ecfa6467438043402594bb2d2b7bd262eb | |
parent | 1bbad9a452390ebc09d038e25ed0307f3fdcd312 (diff) | |
download | chawan-9c257361388f5007871a36eea3abc815a8740d66.tar.gz |
container: fix control char display
Also, kill twidth and its friends; we haven't been using it for a while now. (In the future, a solution with PUA chars might be worth exploring.)
-rw-r--r-- | src/layout/renderdocument.nim | 8 | ||||
-rw-r--r-- | src/local/container.nim | 35 | ||||
-rw-r--r-- | src/local/lineedit.nim | 10 | ||||
-rw-r--r-- | src/local/pager.nim | 2 | ||||
-rw-r--r-- | src/local/select.nim | 4 | ||||
-rw-r--r-- | src/server/buffer.nim | 2 | ||||
-rw-r--r-- | src/utils/strwidth.nim | 21 |
7 files changed, 29 insertions, 53 deletions
diff --git a/src/layout/renderdocument.nim b/src/layout/renderdocument.nim index 5c8ac4a7..7a4797ac 100644 --- a/src/layout/renderdocument.nim +++ b/src/layout/renderdocument.nim @@ -77,7 +77,7 @@ proc findFirstX(line: var FlexibleLine; x: int; outi: var int): int = while cx < x and i < line.str.len: let pi = i let u = line.str.nextUTF8(i) - let w = u.twidth(cx) + let w = u.width() # we must ensure x is max(cx, x), otherwise our assumption of cx <= x # breaks down if cx + w > x: @@ -194,13 +194,13 @@ proc setTextFormat(line: var FlexibleLine; x, cx, nx: int; ostr: string; proc setText(line: var FlexibleLine; linestr: string; x: int; format: Format; node: StyledNode) = assert x >= 0 and linestr.len != 0 - var targetX = x + linestr.twidth(x) + var targetX = x + linestr.width() var i = 0 var cx = line.findFirstX(x, i) # first x of new string (before padding) var j = i var nx = x # last x of new string while nx < targetX and j < line.str.len: - nx += line.str.nextUTF8(j).twidth(nx) + nx += line.str.nextUTF8(j).width() let ostr = line.str.substr(j) line.setTextStr(linestr, ostr, i, x, cx, nx, targetX) line.setTextFormat(x, cx, nx, ostr, format, node) @@ -210,7 +210,7 @@ proc setText(grid: var FlexibleGrid; linestr: string; x, y: int; format: Format; var x = x var i = 0 while x < 0 and i < linestr.len: - x += linestr.nextUTF8(i).twidth(x) + x += linestr.nextUTF8(i).width() if x < 0: # highest x is outside the canvas, no need to draw return diff --git a/src/local/container.nim b/src/local/container.nim index 61db75ec..bbd90f1e 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -308,7 +308,7 @@ func findColBytes(s: string; endx: int; startx = 0; starti = 0): int = var i = starti while i < s.len and w < endx: let u = s.nextUTF8(i) - w += u.twidth(w) + w += u.width() return i func cursorBytes(container: Container; y: int; cc = container.cursorx): int = @@ -327,7 +327,7 @@ func cursorFirstX(container: Container): int = let cc = container.cursorx while i < line.len: let u = line.nextUTF8(i) - let tw = u.twidth(w) + let tw = u.width() if w + tw > cc: return w w += tw @@ -343,7 +343,7 @@ func cursorLastX(container: Container): int = let cc = container.cursorx while i < line.len and w <= cc: let u = line.nextUTF8(i) - w += u.twidth(w) + w += u.width() return max(w - 1, 0) # Last cell for tab, first cell for everything else (e.g. double width.) @@ -361,7 +361,7 @@ func cursorDispX(container: Container): int = while i < line.len and w <= cc: u = line.nextUTF8(i) pw = w - w += u.twidth(w) + w += u.width() if u == uint32('\t'): return max(w - 1, 0) return pw @@ -640,7 +640,7 @@ proc cursorLineTextStart(container: Container) {.jsfunc.} = for u in container.currentLine.points: if not container.luctx.isWhiteSpaceLU(u): break - x += u.twidth(x) + x += u.width() if x == 0: dec x container.setCursorX(x) @@ -745,7 +745,7 @@ proc skipCat(container: Container; b, x: var int; breakFunc: BreakFunc; if container.luctx.breakFunc(u) != cat: b = pb break - x += u.twidth(x) + x += u.width() proc skipSpace(container: Container; b, x: var int; breakFunc: BreakFunc) = container.skipCat(b, x, breakFunc, bcSpace) @@ -858,7 +858,7 @@ proc cursorWordEnd(container: Container; breakFunc: BreakFunc) = b = pb else: px = x - x += u.twidth(x) + x += u.width() container.skipSpace(b, x, breakFunc) # move to the last char in the current category let ob = b @@ -873,7 +873,7 @@ proc cursorWordEnd(container: Container; breakFunc: BreakFunc) = b = pb break px = x - x += u.twidth(x) + x += u.width() x = px if b < container.currentLine.len or ob != b: container.setCursorX(x) @@ -1255,7 +1255,7 @@ proc onMatch(container: Container; res: BufferMatch; refresh: bool) = container.setCursorXYCenter(res.x, res.y, refresh) if container.hlon: container.clearSearchHighlights() - let ex = res.x + res.str.twidth(res.x) - 1 + let ex = res.x + res.str.width() - 1 let hl = Highlight( t: hltSearch, x1: res.x, @@ -1723,7 +1723,7 @@ proc drawLines*(container: Container; display: var FixedGrid; hlcolor: CellColor # Skip cells till fromx. while w < container.fromx and i < line.str.len: let u = line.str.nextUTF8(i) - w += u.twidth(w) + w += u.width() let dls = by * display.width # starting position of row in display # Fill in the gap in case we skipped more cells than fromx mandates (i.e. # we encountered a double-width character.) @@ -1740,25 +1740,20 @@ proc drawLines*(container: Container; display: var FixedGrid; hlcolor: CellColor let pw = w let pi = i let u = line.str.nextUTF8(i) - let uw = u.twidth(w) + let uw = u.width() w += uw if w > container.fromx + display.width: break # die on exceeding the width limit if nf.pos != -1 and nf.pos <= pw: cf = nf nf = line.findNextFormat(pw) - if u == uint32('\t'): - # Needs to be replaced with spaces, otherwise bgcolor isn't displayed. - let tk = k + uw - while k < tk: - display[dls + k].str &= ' ' - set_fmt display[dls + k], cf - inc k + if u <= 0xFF and char(u) in Controls: + display[dls + k].str &= '^' & char(u).getControlLetter() else: for j in pi ..< i: display[dls + k].str &= line.str[j] - set_fmt display[dls + k], cf - k += uw + set_fmt display[dls + k], cf + k += uw if bgcolor != defaultColor: # Fill the screen if bgcolor is not default. while k < display.width: diff --git a/src/local/lineedit.nim b/src/local/lineedit.nim index 2f998b84..f64c37fd 100644 --- a/src/local/lineedit.nim +++ b/src/local/lineedit.nim @@ -26,9 +26,9 @@ type promptw: int state*: LineEditState escNext*: bool - cursorx: int # 0 ..< news.notwidth + cursorx: int # 0 ..< news.width cursori: int # 0 ..< news.len - shiftx: int # 0 ..< news.notwidth + shiftx: int # 0 ..< news.width shifti: int # 0 ..< news.len padding: int # 0 or 1 maxwidth: int @@ -127,7 +127,7 @@ proc insertCharseq(edit: LineEdit; s: string) = return edit.news.insert(s, edit.cursori) edit.cursori += s.len - edit.cursorx += s.notwidth() + edit.cursorx += s.width() edit.redraw = true proc cancel(edit: LineEdit) {.jsfunc.} = @@ -270,7 +270,7 @@ proc begin(edit: LineEdit) {.jsfunc.} = proc `end`(edit: LineEdit) {.jsfunc.} = if edit.cursori < edit.news.len: edit.cursori = edit.news.len - edit.cursorx = edit.news.notwidth() + edit.cursorx = edit.news.width() if edit.cursorx >= edit.shiftx + edit.maxwidth: edit.redraw = true @@ -315,7 +315,7 @@ proc readLine*(prompt, current: string; termwidth: int; disallowed: set[char]; hide: hide, redraw: true, cursori: current.len, - cursorx: current.notwidth(), + cursorx: current.width(), # - 1, so that the cursor always has place maxwidth: termwidth - promptw - 1, hist: hist, diff --git a/src/local/pager.nim b/src/local/pager.nim index 2d0b12f4..f623bf06 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -449,7 +449,7 @@ proc refreshStatusMsg*(pager: Pager) = " (" & $container.atPercentOf() & "%)" & " <" & container.getTitle() let hover = container.getHoverText() - let sl = hover.notwidth() + let sl = hover.width() var l = 0 var i = 0 var maxw = pager.status.grid.width - 1 # -1 for '>' diff --git a/src/local/select.nim b/src/local/select.nim index 70726e7c..766abd1e 100644 --- a/src/local/select.nim +++ b/src/local/select.nim @@ -183,7 +183,7 @@ proc drawBorders(display: var FixedGrid; sx, ex, sy, ey: int; display[y * display.width + x].str = " " inc x else: - #x = display[y * display.width + x].str.twidth(x) + #x = display[y * display.width + x].str.width() inc x # Draw corners. let tl = if upmore: VerticalBar else: CornerTopLeft @@ -261,7 +261,7 @@ proc drawSelect*(select: Select; display: var FixedGrid) = while j < select.options[i].len: let pj = j let u = select.options[i].nextUTF8(j) - let nx = x + u.twidth(x) + let nx = x + u.width() if nx > ex: break display[dls + x].str = select.options[i].substr(pj, j - 1) diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 8a124b2f..858a737c 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -420,7 +420,7 @@ func cursorBytes(buffer: Buffer; y, cc: int): int = var i = 0 while i < line.len and w < cc: let u = line.nextUTF8(i) - w += u.twidth(w) + w += u.width() return i proc navigate(buffer: Buffer; url: URL) = diff --git a/src/utils/strwidth.nim b/src/utils/strwidth.nim index 4ce9aa12..df84dbad 100644 --- a/src/utils/strwidth.nim +++ b/src/utils/strwidth.nim @@ -27,17 +27,10 @@ func width*(u: uint32): int = return 2 return 1 -# Width, but also works with tabs. -# Needs the column width of the text so far. -func twidth*(u: uint32; w: int): int = - if u != uint32('\t'): - return u.width() - return ((w div 8) + 1) * 8 - w - func width*(s: openArray[char]): int = var w = 0 for u in s.points: - w += u.twidth(w) + w += u.width() return w func width*(s: string; start, len: int): int = @@ -48,21 +41,9 @@ func width*(s: string; start, len: int): int = m = s.len while i < m: let u = s.nextUTF8(i) - w += u.twidth(w) - return w - -func notwidth*(s: openArray[char]): int = - var w = 0 - for u in s.points: w += u.width() return w -func twidth*(s: string; w: int): int = - var i = w - for u in s.points: - i += u.twidth(w) - return i - w - func padToWidth*(s: string; size: int; schar = '$'): string = result = newStringOfCap(s.len) var w = 0 |