diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config/config.nim | 6 | ||||
-rw-r--r-- | src/config/toml.nim | 7 | ||||
-rw-r--r-- | src/display/client.nim | 26 | ||||
-rw-r--r-- | src/io/term.nim | 33 | ||||
-rw-r--r-- | src/ips/serialize.nim | 7 | ||||
-rw-r--r-- | src/types/color.nim | 1 |
6 files changed, 64 insertions, 16 deletions
diff --git a/src/config/config.nim b/src/config/config.nim index 131571cb..c8002289 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -25,6 +25,7 @@ type colormode*: Option[ColorMode] formatmode*: Option[FormatMode] altscreen*: Option[bool] + mincontrast*: float func getRealKey(key: string): string = var realk: string @@ -156,6 +157,11 @@ proc parseConfig(config: Config, dir: string, t: TomlValue) = config.hlcolor = parseRGBAColor(v.s).get of "double-width-ambiguous": config.ambiguous_double = v.b + of "minimum-contrast": + if v.vt == VALUE_INTEGER: + config.mincontrast = float(v.i) + else: + config.mincontrast = float(v.f) proc parseConfig(config: Config, dir: string, stream: Stream) = config.parseConfig(dir, parseToml(stream)) diff --git a/src/config/toml.nim b/src/config/toml.nim index 03c17af5..7f743f09 100644 --- a/src/config/toml.nim +++ b/src/config/toml.nim @@ -299,8 +299,8 @@ proc consumeNoState(state: var TomlParser): bool = else: state.syntaxError(fmt"invalid character before key: {c}") state.syntaxError("unexpected end of file") -proc consumeNumber(state: var TomlParser): TomlValue = - var repr: string +proc consumeNumber(state: var TomlParser, c: char): TomlValue = + var repr = $c var isfloat = false if state.has(): if state.peek(0) == '+' or state.peek(0) == '-': @@ -334,6 +334,7 @@ proc consumeNumber(state: var TomlParser): TomlValue = let val = parseFloat64(repr) return TomlValue(vt: VALUE_FLOAT, f: val) + eprint repr let val = parseInt64(repr) return TomlValue(vt: VALUE_INTEGER, i: val) @@ -370,7 +371,7 @@ proc consumeValue(state: var TomlParser): TomlValue = of '#': state.syntaxError("comment without value") of '+', '-', '0'..'9': - return state.consumeNumber() + return state.consumeNumber(c) #TODO date-time of '[': return state.consumeArray() diff --git a/src/display/client.nim b/src/display/client.nim index f4acaee4..05a5a0fc 100644 --- a/src/display/client.nim +++ b/src/display/client.nim @@ -246,16 +246,6 @@ proc inputLoop(client: Client) = if event.fd == client.console.tty.getFileHandle(): client.input() stdout.flushFile() - elif event.fd in client.interval_fdis: - client.intervals[client.interval_fdis[event.fd]].handler() - elif event.fd in client.timeout_fdis: - let id = client.timeout_fdis[event.fd] - let timeout = client.timeouts[id] - timeout.handler() - client.clearTimeout(id) - elif event.fd == sigwinch: - client.attrs = getWindowAttributes(client.console.tty) - client.pager.windowChange(client.attrs) else: let container = client.fdmap[event.fd] if not client.pager.handleEvent(container): @@ -263,10 +253,22 @@ proc inputLoop(client: Client) = for msg in client.pager.status: eprint msg client.quit(1) - elif Error in event.events: + if Error in event.events: eprint "Error", event #TODO handle errors - else: assert false + if Signal in event.events: + if event.fd == sigwinch: + client.attrs = getWindowAttributes(client.console.tty) + client.pager.windowChange(client.attrs) + else: assert false + if Event.Timer in event.events: + if event.fd in client.interval_fdis: + client.intervals[client.interval_fdis[event.fd]].handler() + if event.fd in client.timeout_fdis: + let id = client.timeout_fdis[event.fd] + let timeout = client.timeouts[id] + timeout.handler() + client.clearTimeout(id) if client.pager.scommand != "": client.command(client.pager.scommand) client.pager.scommand = "" diff --git a/src/io/term.nim b/src/io/term.nim index 0406907d..518990e3 100644 --- a/src/io/term.nim +++ b/src/io/term.nim @@ -42,6 +42,7 @@ type cleared: bool prevgrid: FixedGrid attrs*: WindowAttributes + mincontrast: float colormode: ColorMode formatmode: FormatMode smcup: bool @@ -162,6 +163,32 @@ proc disableAltScreen(term: Terminal): string = else: return RMCUP() +proc distance(a, b: CellColor): float = + let a = if a.rgb: + a.rgbcolor + elif a == defaultColor: + ColorsRGB["black"] + else: + ANSIColorMap[a.color mod 10] + let b = if b.rgb: + b.rgbcolor + elif b == defaultColor: + ColorsRGB["white"] + else: + ANSIColorMap[b.color mod 10] + sqrt(float((a.r - b.r) ^ 2 + (a.g - b.b) ^ 2 + (a.g - b.g) ^ 2)) + +proc invert(color: CellColor, bg: bool): CellColor = + if color == defaultColor: + if bg: + return CellColor(rgb: true, rgbcolor: ColorsRGB["white"]) + else: + return CellColor(rgb: true, rgbcolor: ColorsRGB["black"]) + elif color.rgb: + return CellColor(rgb: true, rgbcolor: RGBColor(0xFFFFFF - uint32(color.rgbcolor))) + else: + return CellColor(rgb: true, rgbcolor: RGBColor(0xFFFFFF - uint32(ANSIColorMap[color.color mod 10]))) + # Use euclidian distance to quantize RGB colors. proc approximateANSIColor(rgb: RGBColor, exclude = -1): int = var a = 0 @@ -183,6 +210,11 @@ proc processFormat*(term: Terminal, format: var Format, cellf: Format): string = result &= SGR(FormatCodes[flag].e) var cellf = cellf + if term.mincontrast >= 0 and distance(cellf.bgcolor, cellf.fgcolor) <= term.mincontrast: + cellf.fgcolor = invert(cellf.fgcolor, false) + if distance(cellf.bgcolor, cellf.fgcolor) <= term.mincontrast: + cellf.fgcolor = defaultColor + cellf.bgcolor = defaultColor case term.colormode of ANSI, EIGHT_BIT: if cellf.bgcolor.rgb: @@ -416,6 +448,7 @@ proc detectTermAttributes(term: Terminal) = term.formatmode = term.config.formatmode.get if term.config.altscreen.isSome: term.smcup = term.config.altscreen.get + term.mincontrast = term.config.mincontrast proc start*(term: Terminal, infile: File) = term.infile = infile diff --git a/src/ips/serialize.nim b/src/ips/serialize.nim index 2114cec0..9de0e374 100644 --- a/src/ips/serialize.nim +++ b/src/ips/serialize.nim @@ -5,6 +5,7 @@ import streams import tables import buffer/cell +import config/bufferconfig import io/request import js/regex import types/buffersource @@ -178,6 +179,9 @@ proc swrite*(stream: Stream, source: BufferSource) = stream.swrite(source.location) stream.swrite(source.contenttype) +proc swrite*(stream: Stream, bconfig: BufferConfig) = + stream.swrite(bconfig.userstyle) + template sread*[T](stream: Stream, o: T) = stream.read(o) @@ -307,3 +311,6 @@ proc sread*(stream: Stream, source: var BufferSource) = stream.sread(source.fd) stream.sread(source.location) stream.sread(source.contenttype) + +proc sread*(stream: Stream, bconfig: var BufferConfig) = + stream.sread(bconfig.userstyle) diff --git a/src/types/color.nim b/src/types/color.nim index 9fc00edc..9d3994ff 100644 --- a/src/types/color.nim +++ b/src/types/color.nim @@ -32,7 +32,6 @@ func `==`*(color1, color2: CellColor): bool = const defaultColor* = CellColor(rgb: false, color: 0) -const ANSIFGBlack* = CellColor(rgb: false, color: 38) const ColorsANSIFg* = [ CellColor(rgb: false, color: 30), # black CellColor(rgb: false, color: 31), # red |