barebones in nimsuggest for EPC

This commit is contained in:
Simon Hafner 2015-04-22 21:53:04 +05:00
commit 7d42eb2de2
3 changed files with 104 additions and 27 deletions

View file

@ -9,9 +9,9 @@
## Nimsuggest is a tool that helps to give editors IDE like capabilities. ## Nimsuggest is a tool that helps to give editors IDE like capabilities.
import strutils, os, parseopt, parseUtils import strutils, os, parseopt, parseutils, sequtils
import options, commands, modules, sem, passes, passaux, msgs, nimconf, import options, commands, modules, sem, passes, passaux, msgs, nimconf,
extccomp, condsyms, lists, net, rdstdin, sexp extccomp, condsyms, lists, net, rdstdin, sexp, suggest, ast
const Usage = """ const Usage = """
Nimsuggest - Tool to give every editor IDE like capabilities for Nim Nimsuggest - Tool to give every editor IDE like capabilities for Nim
@ -54,6 +54,35 @@ proc parseQuoted(cmd: string; outp: var string; start: int): int =
i += parseUntil(cmd, outp, seps, i) i += parseUntil(cmd, outp, seps, i)
result = i result = i
# make sure it's in the same order as the proc below
let order: SexpNode =
sexp(@["section", "symkind", "qualifiedPath", "filePath", "forth", "line", "column", "doc"].map(newSSymbol))
proc sexp(s: Section): SexpNode = sexp($s)
proc sexp(s: TSymKind): SexpNode = sexp($s)
proc sexp(s: Suggest): SexpNode =
result = convertSexp([
s.section,
s.symkind,
s.qualifiedPath.map(newSString),
s.filePath,
s.forth,
s.line,
s.column,
s.doc
])
proc sexp(s: seq[Suggest]): SexpNode =
result = sexp(s)
proc listEPC(): SexpNode =
discard
proc executeEPC(body: SexpNode) =
discard
proc action(cmd: string) = proc action(cmd: string) =
template toggle(sw) = template toggle(sw) =
if sw in gGlobalOptions: if sw in gGlobalOptions:
@ -138,7 +167,52 @@ proc serve() =
stdoutSocket.send("\c\L") stdoutSocket.send("\c\L")
stdoutSocket.close() stdoutSocket.close()
of mepc: of mepc:
discard let port = 98294 # guaranteed to be random
var server = newSocket()
server.bindaddr(port.Port, "localhost")
var inp = "".TaintedString
server.listen()
echo(port)
while true:
var results: seq[Suggest] = @[]
var client = newSocket()
suggest.suggestionResultHook = proc (s: Suggest) =
results.add(s)
accept(server, client)
var sizeHex = ""
if client.recv(sizeHex, 6, 1000) != 6:
raise newException(ValueError, "didn't get all the hexbytes")
var size = 0
if parseHex(sizeHex, size) == 0:
raiseRecoverableError("invalid size hex: " & $sizeHex)
var messageBuffer = ""
if client.recv(messageBuffer, size, 3000) != size:
raise newException(ValueError, "didn't get all the bytes")
let message = parseSexp($messageBuffer)
let messageType = message[0].getSymbol
let body = message[1]
case messageType:
of "call":
executeEPC(body)
let response = $sexp(results)
client.send(toHex(len(response), 6))
client.send(response)
client.close()
of "return":
raise newException(ValueError, "no return expected")
of "return-error":
raise newException(ValueError, "no return expected")
of "epc-error":
stderr.writeln("recieved epc error: " & $messageBuffer)
raise newException(ValueError, "epc error")
of "methods":
let response = $listEPC()
client.send(toHex(len(response), 6))
client.send(response)
client.close()
else:
raise newException(ValueError, "unexpected call: " & messageType)
proc mainCommand = proc mainCommand =
registerPass verbosePass registerPass verbosePass
@ -169,7 +243,9 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
gAddress = p.val gAddress = p.val
gMode = mtcp gMode = mtcp
of "stdin": gMode = mstdin of "stdin": gMode = mstdin
of "epc": gMode = mepc of "epc":
gMode = mepc
gVerbosity = 0 # Port number gotta be first.
else: processSwitch(pass, p) else: processSwitch(pass, p)
of cmdArgument: of cmdArgument:
options.gProjectName = unixToNativePath(p.key) options.gProjectName = unixToNativePath(p.key)

View file

@ -11,7 +11,8 @@
# included from sigmatch.nim # included from sigmatch.nim
import algorithm, sequtils, strutils import algorithm, sequtils, strutils, ast, msgs, options, renderer,
types, docgen, lexer, semdata, astalgo, idents, sigmatch, lookups
const const
sep = '\t' sep = '\t'
@ -21,16 +22,16 @@ const
sectionUsage = "use" sectionUsage = "use"
type type
Section = enum sug, def, con, use Section* = enum sug, def, con, use
Suggest = object Suggest* = object
section: Section section*: Section
qualifiedPath: seq[string] qualifiedPath*: seq[string]
filePath: string filePath*: string
line: int # Starts at 1 line*: int # Starts at 1
column: int # Starts at 0 column*: int # Starts at 0
doc: string # Not escaped (yet) doc*: string # Not escaped (yet)
symkind: TSymKind symkind*: TSymKind
forth: string # XXX TODO object on symkind forth*: string # XXX TODO object on symkind
var var
suggestionResultHook*: proc (result: Suggest) {.closure.} suggestionResultHook*: proc (result: Suggest) {.closure.}

View file

@ -293,7 +293,7 @@ proc raiseParseErr*(p: SexpParser, msg: string) {.noinline, noreturn.} =
## raises an `ESexpParsingError` exception. ## raises an `ESexpParsingError` exception.
raise newException(SexpParsingError, errorMsgExpected(p, msg)) raise newException(SexpParsingError, errorMsgExpected(p, msg))
proc newSString*(s: string): SexpNode = proc newSString*(s: string): SexpNode {.procvar.}=
## Creates a new `SString SexpNode`. ## Creates a new `SString SexpNode`.
new(result) new(result)
result.kind = SString result.kind = SString
@ -304,36 +304,36 @@ proc newSStringMove(s: string): SexpNode =
result.kind = SString result.kind = SString
shallowCopy(result.str, s) shallowCopy(result.str, s)
proc newSInt*(n: BiggestInt): SexpNode = proc newSInt*(n: BiggestInt): SexpNode {.procvar.} =
## Creates a new `SInt SexpNode`. ## Creates a new `SInt SexpNode`.
new(result) new(result)
result.kind = SInt result.kind = SInt
result.num = n result.num = n
proc newSFloat*(n: float): SexpNode = proc newSFloat*(n: float): SexpNode {.procvar.} =
## Creates a new `SFloat SexpNode`. ## Creates a new `SFloat SexpNode`.
new(result) new(result)
result.kind = SFloat result.kind = SFloat
result.fnum = n result.fnum = n
proc newSNil*(): SexpNode = proc newSNil*(): SexpNode {.procvar.} =
## Creates a new `SNil SexpNode`. ## Creates a new `SNil SexpNode`.
new(result) new(result)
proc newSCons*(car, cdr: SexpNode): SexpNode = proc newSCons*(car, cdr: SexpNode): SexpNode {.procvar.} =
## Creates a new `SCons SexpNode` ## Creates a new `SCons SexpNode`
new(result) new(result)
result.kind = SCons result.kind = SCons
result.car = car result.car = car
result.cdr = cdr result.cdr = cdr
proc newSList*(): SexpNode = proc newSList*(): SexpNode {.procvar.} =
## Creates a new `SList SexpNode` ## Creates a new `SList SexpNode`
new(result) new(result)
result.kind = SList result.kind = SList
result.elems = @[] result.elems = @[]
proc newSSymbol*(s: string): SexpNode = proc newSSymbol*(s: string): SexpNode {.procvar.} =
new(result) new(result)
result.kind = SSymbol result.kind = SSymbol
result.symbol = s result.symbol = s
@ -387,25 +387,25 @@ proc getCons*(n: SexpNode, defaults: Cons = (newSNil(), newSNil())): Cons =
elif n.kind == SList: return (n.elems[0], n.elems[1]) elif n.kind == SList: return (n.elems[0], n.elems[1])
else: return defaults else: return defaults
proc `sexp`*(s: string): SexpNode = proc sexp*(s: string): SexpNode =
## Generic constructor for SEXP data. Creates a new `SString SexpNode`. ## Generic constructor for SEXP data. Creates a new `SString SexpNode`.
new(result) new(result)
result.kind = SString result.kind = SString
result.str = s result.str = s
proc `sexp`*(n: BiggestInt): SexpNode = proc sexp*(n: BiggestInt): SexpNode =
## Generic constructor for SEXP data. Creates a new `SInt SexpNode`. ## Generic constructor for SEXP data. Creates a new `SInt SexpNode`.
new(result) new(result)
result.kind = SInt result.kind = SInt
result.num = n result.num = n
proc `sexp`*(n: float): SexpNode = proc sexp*(n: float): SexpNode =
## Generic constructor for SEXP data. Creates a new `SFloat SexpNode`. ## Generic constructor for SEXP data. Creates a new `SFloat SexpNode`.
new(result) new(result)
result.kind = SFloat result.kind = SFloat
result.fnum = n result.fnum = n
proc `sexp`*(b: bool): SexpNode = proc sexp*(b: bool): SexpNode =
## Generic constructor for SEXP data. Creates a new `SSymbol ## Generic constructor for SEXP data. Creates a new `SSymbol
## SexpNode` with value t or `SNil SexpNode`. ## SexpNode` with value t or `SNil SexpNode`.
new(result) new(result)
@ -415,7 +415,7 @@ proc `sexp`*(b: bool): SexpNode =
else: else:
result.kind = SNil result.kind = SNil
proc `sexp`*(elements: openArray[SexpNode]): SexpNode = proc sexp*(elements: openArray[SexpNode]): SexpNode =
## Generic constructor for SEXP data. Creates a new `SList SexpNode` ## Generic constructor for SEXP data. Creates a new `SList SexpNode`
new(result) new(result)
result.kind = SList result.kind = SList