import std/deques
import std/net
import std/options
import std/os
import std/osproc
import std/selectors
import std/streams
import std/tables
import std/unicode
when defined(posix):
import std/posix
import bindings/libregexp
import config/config
import config/mailcap
import io/posixstream
import io/promise
import io/serialize
import io/socketstream
import io/stdio
import io/tempfile
import io/urlfilter
import js/error
import js/javascript
import js/jstypes
import js/regex
import js/tojs
import loader/connecterror
import loader/headers
import loader/loader
import loader/request
import local/container
import local/lineedit
import local/select
import local/term
import server/buffer
import server/forkserver
import types/cell
import types/color
import types/cookie
import types/opt
import types/url
import types/winattrs
import utils/strwidth
import utils/twtstr
import chagashi/charset
type
LineMode* = enum
lmLocation = "URL: "
lmUsername = "Username: "
lmPassword = "Password: "
lmCommand = "COMMAND: "
lmBuffer = "(BUFFER) "
lmSearchF = "/"
lmSearchB = "?"
lmISearchF = "/"
lmISearchB = "?"
lmGotoLine = "Goto line: "
lmDownload = "(Download)Save file to: "
# fdin is the original fd; fdout may be the same, or different if mailcap
# is used.
ProcMapItem = object
container*: Container
fdin*: FileHandle
fdout*: FileHandle
istreamOutputId*: int
ostreamOutputId*: int
PagerAlertState = enum
pasNormal, pasAlertOn, pasLoadInfo
ContainerConnectionState = enum
ccsBeforeResult, ccsBeforeStatus, ccsBeforeHeaders
ConnectingContainerItem = ref object
state: ContainerConnectionState
container: Container
stream*: SocketStream
res: int
outputId: int
status: uint16
LineData = ref object of RootObj
LineDataDownload = ref object of LineData
outputId: int
stream: Stream
LineDataAuth = ref object of LineData
url: URL
username: string
Pager* = ref object
alertState: PagerAlertState
alerts*: seq[string]
askcharpromise*: Promise[string]
askcursor: int
askpromise*: Promise[bool]
askprompt: string
commandMode {.jsget.}: bool
config*: Config
connectingContainers*: seq[ConnectingContainerItem]
container*: Container
cookiejars: Table[string, CookieJar]
devRandom: PosixStream
display: FixedGrid
forkserver*: ForkServer
hasload*: bool # has a page been successfully loaded since startup?
inputBuffer*: string # currently uninterpreted characters
iregex: Result[Regex, string]
isearchpromise: EmptyPromise
lineData: LineData
lineedit*: Option[LineEdit]
linehist: array[LineMode, LineHistory]
linemode: LineMode
loader*: FileLoader
notnum*: bool # has a non-numeric character been input already?
numload*: int # number of pages currently being loaded
precnum*: int32 # current number prefix (when vi-numeric-prefix is true)
procmap*: seq[ProcMapItem]
redraw: bool
regex: Opt[Regex]
reverseSearch: bool
scommand*: string
selector*: Selector[int]
statusgrid*: FixedGrid
term*: Terminal
unreg*: seq[Container]
jsDestructor(Pager)
template attrs(pager: Pager): WindowAttributes =
pager.term.attrs
func loaderPid(pager: Pager): int64 {.jsfget.} =
int64(pager.loader.process)
func getRoot(container: Container): Container =
var c = container
while c.parent != nil: c = c.parent
return c
# depth-first descendant iterator
iterator descendants(parent: Container): Container {.inline.} =
var stack = newSeqOfCap[Container](parent.children.len)
for i in countdown