diff options
author | bptato <nincsnevem662@gmail.com> | 2021-12-26 22:17:24 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2021-12-26 22:17:24 +0100 |
commit | 647089a99e3c44c4115274a8822ca0a4dd947d67 (patch) | |
tree | 1fa85f4e12676ef8532ff2c9eaaa065a0bcd263a /src/io | |
parent | 9c688a75adcd647723a993f04cb964d62e7f05a4 (diff) | |
download | chawan-647089a99e3c44c4115274a8822ca0a4dd947d67.tar.gz |
Proper URL handling
Diffstat (limited to 'src/io')
-rw-r--r-- | src/io/buffer.nim | 49 | ||||
-rw-r--r-- | src/io/cell.nim | 105 |
2 files changed, 87 insertions, 67 deletions
diff --git a/src/io/buffer.nim b/src/io/buffer.nim index 56de9938..2610d9b1 100644 --- a/src/io/buffer.nim +++ b/src/io/buffer.nim @@ -1,6 +1,5 @@ -import os +import options import terminal -import uri import unicode import css/cascade @@ -12,6 +11,7 @@ import io/cell import layout/box import render/renderdocument import render/rendertext +import types/url import utils/twtstr type @@ -34,7 +34,7 @@ type redraw*: bool reshape*: bool nostatus*: bool - location*: Uri + location*: Url target*: string source*: string showsource*: bool @@ -151,9 +151,7 @@ func generateSwapOutput(buffer: Buffer): string = #if text.len > 0: # result &= $text -func generateStatusMessage(buffer: Buffer): string = - result &= HVP(buffer.height + 1, 1) - result &= SGR() +func generateStatusMessage*(buffer: Buffer): string = var formatting = newFormatting() var w = 0 for cell in buffer.statusmsg: @@ -162,7 +160,6 @@ func generateStatusMessage(buffer: Buffer): string = w += cell.width() if w < buffer.width: result &= EL() - result &= SGR() func numLines*(buffer: Buffer): int = buffer.lines.len @@ -259,6 +256,14 @@ func atPercentOf(buffer: Buffer): int = func hasAnchor*(buffer: Buffer, anchor: string): bool = return buffer.document.getElementById(anchor) != nil +func getTitle(buffer: Buffer): string = + let titles = buffer.document.getElementsByTag(TAG_TITLE) + if titles.len > 0: + for text in titles[0].textNodes: + result &= text.data.strip().clearControls() + else: + result = $buffer.location + proc clearDisplay(buffer: Buffer) = buffer.prevdisplay = buffer.display buffer.display = newFixedGrid(buffer.width, buffer.height) @@ -645,11 +650,11 @@ proc gotoAnchor*(buffer: Buffer) = return inc i -proc setLocation*(buffer: Buffer, uri: Uri) = - buffer.location = uri +proc setLocation*(buffer: Buffer, location: Url) = + buffer.location = location -proc gotoLocation*(buffer: Buffer, uri: Uri) = - buffer.location = buffer.location.combine(uri) +proc gotoLocation*(buffer: Buffer, s: string) = + discard parseUrl(s, buffer.location.some, buffer.location, true) proc refreshTermAttrs*(buffer: Buffer): bool = let newAttrs = getTermAttributes() @@ -668,21 +673,6 @@ proc updateCursor(buffer: Buffer) = if buffer.lines.len == 0: buffer.cursory = 0 -#TODO -func mergeUri*(urla, urlb: Uri): Uri = - var moduri = urlb - if moduri.scheme == "": - moduri.scheme = urla.scheme - if moduri.scheme == "": - moduri.scheme = "file" - if moduri.hostname == "": - moduri.hostname = urla.hostname - if moduri.path == "": - moduri.path = urla.path - elif urla.path != "": - moduri.path = urla.path.splitFile().dir / moduri.path - return moduri - proc updateHover(buffer: Buffer) = let nodes = buffer.currentDisplayCell().nodes if nodes != buffer.prevnodes: @@ -701,7 +691,7 @@ proc updateHover(buffer: Buffer) = let link = nodes.getLink() if link != nil: if link.tagType == TAG_A: - buffer.hovertext = $buffer.location.mergeUri(parseUri(HTMLAnchorElement(link).href)) + buffer.hovertext = parseUrl(HTMLAnchorElement(link).href, buffer.location.some).serialize() else: buffer.hovertext = "" for node in buffer.prevnodes: @@ -767,7 +757,10 @@ proc displayBuffer(buffer: Buffer) = print(buffer.generateFullOutput()) proc displayStatusMessage*(buffer: Buffer) = + print(HVP(buffer.height + 1, 1)) + print(SGR()) print(buffer.generateStatusMessage()) + print(SGR()) proc click*(buffer: Buffer): string = let link = buffer.getCursorLink() @@ -790,7 +783,7 @@ proc drawBuffer*(buffer: Buffer) = print(line.str.substr(x, line.str.len) & '\n') proc refreshBuffer*(buffer: Buffer) = - buffer.title = $buffer.location + buffer.title = buffer.getTitle() stdout.hideCursor() if buffer.refreshTermAttrs(): diff --git a/src/io/cell.nim b/src/io/cell.nim index f477bafd..f5fb9721 100644 --- a/src/io/cell.nim +++ b/src/io/cell.nim @@ -1,11 +1,12 @@ -import unicode -import strutils import sequtils +import streams +import strutils import sugar +import unicode +import html/dom import types/color import utils/twtstr -import html/dom type FormatFlags* = enum @@ -48,13 +49,6 @@ const FormatCodes: array[FormatFlags, tuple[s: int, e: int]] = [ FLAG_OVERLINE: (53, 55), ] -func bold(formatting: Formatting): bool = FLAG_BOLD in formatting.flags -func italic(formatting: Formatting): bool = FLAG_ITALIC in formatting.flags -func underline(formatting: Formatting): bool = FLAG_UNDERLINE in formatting.flags -func reverse(formatting: Formatting): bool = FLAG_REVERSE in formatting.flags -func strike(formatting: Formatting): bool = FLAG_STRIKE in formatting.flags -func overline(formatting: Formatting): bool = FLAG_OVERLINE in formatting.flags - template flag_template(formatting: Formatting, val: bool, flag: FormatFlags) = if val: formatting.flags.incl(flag) else: formatting.flags.excl(flag) @@ -140,6 +134,9 @@ proc add*(a: var FlexibleLine, b: FlexibleLine) = proc addLine*(grid: var FlexibleGrid) = grid.add(FlexibleLine()) +proc addFormat*(line: var FlexibleLine, pos: int, format: Formatting) = + line.formats.add(FormattingCell(formatting: format, pos: line.str.len)) + proc addFormat*(grid: var FlexibleGrid, y, pos: int, format: Formatting) = grid[y].formats.add(FormattingCell(formatting: format, pos: grid[y].str.len)) @@ -157,35 +154,7 @@ template inc_check(i: int) = if i >= buf.len: return i -proc parseAnsiCode*(formatting: var Formatting, buf: string, fi: int): int = - var i = fi - if buf[i] != '\e': - return i - - inc_check i - if 0x40 <= int(buf[i]) and int(buf[i]) <= 0x5F: - if buf[i] != '[': - #C1, TODO? - return - inc_check i - - let sp = i - #parameter bytes - while 0x30 <= int(buf[i]) and int(buf[i]) <= 0x3F: - inc_check i - let params = buf.substr(sp, i - 1) - - let si = i - #intermediate bytes - while 0x20 <= int(buf[i]) and int(buf[i]) <= 0x2F: - inc_check i - #let interm = buf.substr(si, i) - - let final = buf[i] - #final byte - if 0x40 <= int(buf[i]) and int(buf[i]) <= 0x7E: - inc_check i - +proc handleAnsiCode(formatting: var Formatting, final: char, params: string) = case final of 'm': if params.len == 0: @@ -257,8 +226,66 @@ proc parseAnsiCode*(formatting: var Formatting, buf: string, fi: int): int = except ValueError: discard else: discard +proc parseAnsiCode*(formatting: var Formatting, buf: string, fi: int): int = + var i = fi + if buf[i] != '\e': + return i + + inc_check i + if 0x40 <= int(buf[i]) and int(buf[i]) <= 0x5F: + if buf[i] != '[': + #C1, TODO? + return + inc_check i + + let sp = i + #parameter bytes + while 0x30 <= int(buf[i]) and int(buf[i]) <= 0x3F: + inc_check i + let params = buf.substr(sp, i - 1) + + let si = i + #intermediate bytes + while 0x20 <= int(buf[i]) and int(buf[i]) <= 0x2F: + inc_check i + #let interm = buf.substr(si, i) + + let final = buf[i] + #final byte + if 0x40 <= int(buf[i]) and int(buf[i]) <= 0x7E: + formatting.handleAnsiCode(final, params) + return i +proc parseAnsiCode*(formatting: var Formatting, stream: Stream) = + if stream.atEnd(): return + var c = stream.readChar() + if 0x40 <= int(c) and int(c) <= 0x5F: + if c != '[': + #C1, TODO? + return + if stream.atEnd(): return + c = stream.readChar() + + var params = $c + #parameter bytes + while 0x30 <= int(c) and int(c) <= 0x3F: + params &= c + if stream.atEnd(): return + c = stream.readChar() + + #intermediate bytes + #var interm = $c + while 0x20 <= int(c) and int(c) <= 0x2F: + #interm &= c + if stream.atEnd(): return + c = stream.readChar() + + #final byte + if 0x40 <= int(c) and int(c) <= 0x7E: + let final = c + formatting.handleAnsiCode(final, params) + proc processFormatting*(formatting: var Formatting, cellf: Formatting): string = for flag in FormatFlags: if flag in formatting.flags and flag notin cellf.flags: |