about summary refs log tree commit diff stats
path: root/src/display
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-12-13 00:04:50 +0100
committerbptato <nincsnevem662@gmail.com>2022-12-13 00:04:50 +0100
commitd9e430c8147c8c2d81b4ca5405786269b2cfc94d (patch)
tree91ddb6edbedc6e8310fedc13106b8b3bdcec2cdc /src/display
parent7a3fb32bff44a581d6926bfaf5f070f8ef062338 (diff)
downloadchawan-d9e430c8147c8c2d81b4ca5405786269b2cfc94d.tar.gz
Add all sorts of config options and cookies
Diffstat (limited to 'src/display')
-rw-r--r--src/display/client.nim8
-rw-r--r--src/display/pager.nim59
-rw-r--r--src/display/term.nim35
3 files changed, 67 insertions, 35 deletions
diff --git a/src/display/client.nim b/src/display/client.nim
index 7bf9a278..90945968 100644
--- a/src/display/client.nim
+++ b/src/display/client.nim
@@ -48,7 +48,7 @@ type
     pager {.jsget.}: Pager
     line {.jsget.}: LineEdit
     sevent: seq[Container]
-    config: Config
+    config {.jsget.}: Config
     jsrt: JSRuntime
     jsctx: JSContext
     timeoutid: int
@@ -466,7 +466,9 @@ proc newClient*(config: Config, dispatcher: Dispatcher): Client =
   result.jsrt.setInterruptHandler(interruptHandler, cast[pointer](result))
   let ctx = result.jsrt.newJSContext()
   result.jsctx = ctx
-  result.pager = newPager(config, result.attrs, dispatcher, result.config.getSiteConfig(ctx))
+  result.pager = newPager(config, result.attrs, dispatcher,
+                          result.config.getSiteConfig(ctx),
+                          result.config.getOmniRules(ctx))
   var global = ctx.getGlobalObject()
   ctx.registerType(Client, asglobal = true)
   global.setOpaque(result)
@@ -481,5 +483,7 @@ proc newClient*(config: Config, dispatcher: Dispatcher): Client =
   ctx.addHTMLModule()
   ctx.addRequestModule()
   ctx.addLineEditModule()
+  ctx.addConfigModule()
   ctx.addPagerModule()
   ctx.addContainerModule()
+  ctx.addConfigModule()
diff --git a/src/display/pager.nim b/src/display/pager.nim
index 765e1e73..06b28346 100644
--- a/src/display/pager.nim
+++ b/src/display/pager.nim
@@ -1,3 +1,4 @@
+import deques
 import net
 import options
 import os
@@ -22,6 +23,7 @@ import js/javascript
 import js/regex
 import types/buffersource
 import types/color
+import types/cookie
 import types/dispatcher
 import types/url
 import utils/twtstr
@@ -55,6 +57,8 @@ type
     term*: Terminal
     linehist: array[LineMode, LineHistory]
     siteconf: seq[SiteConfig]
+    omnirules: seq[OmniRule]
+    cookiejars: Table[string, CookieJar]
 
 func attrs(pager: Pager): WindowAttributes = pager.term.attrs
 
@@ -147,7 +151,7 @@ proc isearchBackward(pager: Pager) {.jsfunc.} =
   pager.container.pushCursorPos()
   pager.setLineEdit("?", ISEARCH_B)
 
-proc newPager*(config: Config, attrs: WindowAttributes, dispatcher: Dispatcher, siteconf: seq[SiteConfig]): Pager =
+proc newPager*(config: Config, attrs: WindowAttributes, dispatcher: Dispatcher, siteconf: seq[SiteConfig], omnirules: seq[OmniRule]): Pager =
   let pager = Pager(
     dispatcher: dispatcher,
     config: config,
@@ -156,9 +160,13 @@ proc newPager*(config: Config, attrs: WindowAttributes, dispatcher: Dispatcher,
     term: newTerminal(stdout, config, attrs),
   )
   for sc in siteconf:
-    # not sure why but normal copies don't seem to work here...
+    # not sure why but normal copies don't seem to work here... probably
+    # something weird going on with lambdas
     pager.siteconf.add(sc)
     pager.siteconf[^1].subst = sc.subst
+  for rule in omnirules:
+    pager.omnirules.add(rule)
+    pager.omnirules[^1].subst = rule.subst
   return pager
 
 proc launchPager*(pager: Pager, tty: File) =
@@ -304,7 +312,7 @@ proc draw*(pager: Pager) =
     pager.term.writeGrid(pager.statusgrid, 0, pager.attrs.height - 1)
   pager.term.outputGrid()
   if pager.lineedit.isSome:
-    pager.term.setCursor(pager.lineedit.get.getCursorX(), pager.container.attrs.height - 1)
+    pager.term.setCursor(pager.lineedit.get.getCursorX(), pager.attrs.height - 1)
   else:
     pager.term.setCursor(pager.container.acursorx, pager.container.acursory)
   pager.term.showCursor()
@@ -459,21 +467,24 @@ proc windowChange*(pager: Pager, attrs: WindowAttributes) =
   for container in pager.containers:
     container.windowChange(attrs)
 
-# ugh...
-proc substituteUrl(pager: Pager, request: Request) =
-  let surl = $request.url
+proc applySiteconf(pager: Pager, request: Request) =
+  let url = $request.url
+  let host = $request.url.host
   for sc in pager.siteconf:
-    if sc.url.exec(surl).success:
-      let s = sc.subst(surl)
-      if s.isSome:
-        let nurl = parseURL(s.get)
-        if nurl.isSome:
-          request.url = nurl.get
-      break
+    if sc.url.isSome and not sc.url.get.exec(url).success:
+      continue
+    elif sc.host.isSome and not sc.host.get.exec(host).success:
+      continue
+    if sc.subst != nil:
+      let s = sc.subst(request.url)
+      if s.isSome and s.get != nil:
+        request.url = s.get
+    if sc.cookie and request.url.host notin pager.cookiejars:
+      pager.cookiejars[request.url.host] = newCookieJar(request.url)
 
 # Load request in a new buffer.
 proc gotoURL*(pager: Pager, request: Request, prevurl = none(URL), ctype = none(string), replace: Container = nil) =
-  pager.substituteUrl(request)
+  pager.applySiteconf(request)
   if prevurl.isnone or not prevurl.get.equals(request.url, true) or
       request.url.hash == "" or request.httpmethod != HTTP_GET:
     # Basically, we want to reload the page *only* when
@@ -488,7 +499,8 @@ proc gotoURL*(pager: Pager, request: Request, prevurl = none(URL), ctype = none(
       contenttype: ctype,
       location: request.url
     )
-    let container = pager.dispatcher.newBuffer(pager.config, source)
+    let cookiejar = pager.cookiejars.getOrDefault(request.url.host)
+    let container = pager.dispatcher.newBuffer(pager.config, source, cookiejar)
     if replace != nil:
       container.replace = replace
       container.copyCursorPos(container.replace)
@@ -497,6 +509,12 @@ proc gotoURL*(pager: Pager, request: Request, prevurl = none(URL), ctype = none(
   else:
     pager.container.findAnchor(request.url.anchor)
 
+proc omniRewrite(pager: Pager, s: string): string =
+  for rule in pager.omnirules:
+    if rule.match.exec(s).success:
+      return rule.subst(s).get
+  return s
+
 # When the user has passed a partial URL as an argument, they might've meant
 # either:
 # * file://$PWD/<file>
@@ -504,6 +522,8 @@ proc gotoURL*(pager: Pager, request: Request, prevurl = none(URL), ctype = none(
 # So we attempt to load both, and see what works.
 # (TODO: make this optional)
 proc loadURL*(pager: Pager, url: string, ctype = none(string)) =
+  let url0 = pager.omniRewrite(url)
+  let url = if url[0] == '~': expandPath(url0) else: url0
   let firstparse = parseURL(url)
   if firstparse.issome:
     let prev = if pager.container != nil:
@@ -518,7 +538,6 @@ proc loadURL*(pager: Pager, url: string, ctype = none(string)) =
     if pageurl.isSome: # attempt to load remote page
       urls.add(pageurl.get)
   let cdir = parseURL("file://" & getCurrentDir() & DirSep)
-  let url = if url[0] == '~': expandPath(url) else: url
   let purl = percentEncode(url, LocalPathPercentEncodeSet)
   if purl != url:
     let newurl = parseURL(purl, cdir)
@@ -542,7 +561,7 @@ proc readPipe0*(pager: Pager, ctype: Option[string], fd: FileHandle, location: O
     contenttype: some(ctype.get("text/plain")),
     location: location.get(newURL("file://-"))
   )
-  let container = pager.dispatcher.newBuffer(pager.config, source, title)
+  let container = pager.dispatcher.newBuffer(pager.config, source, nil, title)
   return container
 
 proc readPipe*(pager: Pager, ctype: Option[string], fd: FileHandle) =
@@ -726,12 +745,16 @@ proc handleEvent0(pager: Pager, container: Container, event: ContainerEvent): bo
     if pager.container == container:
       pager.alert(event.msg)
       pager.refreshStatusMsg()
+  of SET_COOKIE:
+    let host = container.source.location.host
+    if host in pager.cookiejars:
+      pager.cookiejars[host].cookies.add(event.cookies)
   of NO_EVENT: discard
   return true
 
 proc handleEvents*(pager: Pager, container: Container): bool =
   while container.events.len > 0:
-    let event = container.events.pop()
+    let event = container.events.popFirst()
     if not pager.handleEvent0(container, event):
       return false
   return true
diff --git a/src/display/term.nim b/src/display/term.nim
index 073b5dfc..247f356d 100644
--- a/src/display/term.nim
+++ b/src/display/term.nim
@@ -386,7 +386,26 @@ proc writeGrid*(term: Terminal, grid: FixedGrid, x = 0, y = 0) =
             cell.format.fgcolor = grid[(ly - y) * grid.width + (lx - x)].format.fgcolor
           j += cell[].width()
 
+proc applyConfig(term: Terminal) =
+  if term.config.colormode.isSome:
+    term.colormode = term.config.colormode.get
+  elif term.isatty():
+    term.colormode = ANSI
+    let colorterm = getEnv("COLORTERM")
+    case colorterm
+    of "24bit", "truecolor": term.colormode = TRUE_COLOR
+  if term.config.formatmode.isSome:
+    term.formatmode = term.config.formatmode.get
+  for fm in FormatFlags:
+    if fm in term.config.noformatmode:
+      term.formatmode.excl(fm)
+  if term.isatty() and term.config.altscreen.isSome:
+    term.smcup = term.config.altscreen.get
+  term.mincontrast = term.config.mincontrast
+
 proc outputGrid*(term: Terminal) =
+  if term.config.termreload:
+    term.applyConfig()
   term.outfile.write(term.resetFormat())
   if term.config.forceclear or not term.cleared:
     term.outfile.write(term.generateFullOutput(term.canvas))
@@ -488,21 +507,7 @@ proc detectTermAttributes(term: Terminal) =
     if term.isatty():
       term.smcup = true
       term.formatmode = {low(FormatFlags)..high(FormatFlags)}
-  if term.config.colormode.isSome:
-    term.colormode = term.config.colormode.get
-  elif term.isatty():
-    term.colormode = ANSI
-    let colorterm = getEnv("COLORTERM")
-    case colorterm
-    of "24bit", "truecolor": term.colormode = TRUE_COLOR
-  if term.config.formatmode.isSome:
-    term.formatmode = term.config.formatmode.get
-  for fm in FormatFlags:
-    if fm in term.config.noformatmode:
-      term.formatmode.excl(fm)
-  if term.isatty() and term.config.altscreen.isSome:
-    term.smcup = term.config.altscreen.get
-  term.mincontrast = term.config.mincontrast
+  term.applyConfig()
 
 proc start*(term: Terminal, infile: File) =
   term.infile = infile