import tables import os import strutils import utils/twtstr import utils/radixtree type TwtAction* = enum NO_ACTION, ACTION_FEED_NEXT, ACTION_QUIT, ACTION_CURSOR_UP, ACTION_CURSOR_DOWN, ACTION_CURSOR_LEFT, ACTION_CURSOR_RIGHT, ACTION_CURSOR_LINEEND, ACTION_CURSOR_LINEBEGIN, ACTION_CURSOR_NEXT_WORD, ACTION_CURSOR_PREV_WORD, ACTION_CURSOR_NEXT_NODE, ACTION_CURSOR_PREV_NODE, ACTION_CURSOR_NEXT_LINK, ACTION_CURSOR_PREV_LINK, ACTION_PAGE_DOWN, ACTION_PAGE_UP, ACTION_PAGE_LEFT, ACTION_PAGE_RIGHT, ACTION_HALF_PAGE_DOWN, ACTION_HALF_PAGE_UP, ACTION_SCROLL_DOWN, ACTION_SCROLL_UP, ACTION_SCROLL_LEFT, ACTION_SCROLL_RIGHT, ACTION_CLICK, ACTION_CHANGE_LOCATION, ACTION_RELOAD, ACTION_RESHAPE, ACTION_REDRAW, ACTION_TOGGLE_SOURCE, ACTION_CURSOR_FIRST_LINE, ACTION_CURSOR_LAST_LINE, ACTION_CURSOR_TOP, ACTION_CURSOR_MIDDLE, ACTION_CURSOR_BOTTOM, ACTION_CENTER_LINE, ACTION_LINE_INFO, ACTION_LINED_SUBMIT, ACTION_LINED_CANCEL, ACTION_LINED_BACKSPACE, ACTION_LINED_DELETE, ACTION_LINED_CLEAR, ACTION_LINED_KILL, ACTION_LINED_KILL_WORD, ACTION_LINED_BACK, ACTION_LINED_FORWARD, ACTION_LINED_PREV_WORD, ACTION_LINED_NEXT_WORD, ACTION_LINED_BEGIN, ACTION_LINED_END, ACTION_LINED_COMPOSE_TOGGLE, ACTION_LINED_ESC ActionMap = Table[string, TwtAction] StaticConfig = object nmap: ActionMap lemap: ActionMap Config = object nmap*: ActionMap lemap*: ActionMap func getConfig(s: StaticConfig): Config = return Config(nmap: s.nmap, lemap: s.lemap) func getRealKey(key: string): string = var realk: string var control = 0 var meta = 0 var skip = false for c in key: if c == '\\': skip = true elif skip: realk &= c skip = false elif c == 'M' and meta == 0: inc meta elif c == 'C' and control == 0: inc control elif c == '-' and control == 1: inc control elif c == '-' and meta == 1: inc meta elif meta == 1: realk &= 'M' & c meta = 0 elif meta == 2: realk &= '\e' realk &= c meta = 0 elif control == 1: realk &= 'C' & c control = 0 elif control == 2: realk &= getControlChar(c) control = 0 else: realk &= c if control == 1: realk &= 'C' if meta == 1: realk &= 'M' return realk func constructActionTable*(origTable: ActionMap): ActionMap = var newTable: ActionMap var strs: seq[string] for k in origTable.keys: let realk = getRealKey(k) var teststr = "" for c in realk: teststr &= c strs.add(teststr) for k, v in origTable: let realk = getRealKey(k) var teststr = "" for c in realk: teststr &= c if strs.contains(teststr): newTable[teststr] = ACTION_FEED_NEXT newTable[realk] = v return newTable proc parseConfigLine[T](line: string, config: var T) = if line.len == 0 or line[0] == '#': return let cmd = line.split(' ') if cmd.len == 3: if cmd[0] == "nmap": config.nmap[getRealKey(cmd[1])] = parseEnum[TwtAction]("ACTION_" & cmd[2]) elif cmd[0] == "lemap": config.lemap[getRealKey(cmd[1])] = parseEnum[TwtAction]("ACTION_" & cmd[2]) proc staticReadConfig(): StaticConfig = let default = staticRead"res/config" for line in default.split('\n'): parseConfigLine(line, result) result.nmap = constructActionTable(result.nmap) result.lemap = constructActionTable(result.lemap) const defaultConfig = staticReadConfig() var gconfig* = getConfig(defaultConfig) proc readConfig(filename: string) = var f: File let status = f.open(filename, fmRead) var nmap: ActionMap var lemap: ActionMap if status: var line: TaintedString while f.readLine(line): parseConfigLine(line, gconfig) gconfig.nmap = constructActionTable(nmap) gconfig.lemap = constructActionTable(lemap) proc readConfig*() = when defined(debug): readConfig("res" / "config") readConfig(getConfigDir() / "twt" / "config") proc getNormalAction*(s: string): TwtAction = if gconfig.nmap.hasKey(s): return gconfig.nmap[s] return NO_ACTION proc getLinedAction*(s: string): TwtAction = if gconfig.lemap.hasKey(s): return gconfig.lemap[s] return NO_ACTION