nimsuggest supports prefix matching (first version)

This commit is contained in:
Araq
2017-02-28 09:03:40 +01:00
parent e78bd69619
commit 3d46600a90
6 changed files with 126 additions and 174 deletions

View File

@@ -1,7 +1,7 @@
#
#
# The Nim Compiler
# (c) Copyright 2016 Andreas Rumpf
# (c) Copyright 2017 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@@ -50,7 +50,7 @@ In addition, all command line options of Nim that do not affect code generation
are supported.
"""
type
Mode = enum mstdin, mtcp, mepc
Mode = enum mstdin, mtcp, mepc, mcmdline
var
gPort = 6000.Port
@@ -133,7 +133,8 @@ proc symFromInfo(graph: ModuleGraph; gTrackPos: TLineInfo): PSym =
proc execute(cmd: IdeCmd, file, dirtyfile: string, line, col: int;
graph: ModuleGraph; cache: IdentCache) =
if gLogging:
logStr("cmd: " & $cmd & ", file: " & file & ", dirtyFile: " & dirtyfile & "[" & $line & ":" & $col & "]")
logStr("cmd: " & $cmd & ", file: " & file & ", dirtyFile: " & dirtyfile &
"[" & $line & ":" & $col & "]")
gIdeCmd = cmd
if cmd == ideUse and suggestVersion != 2:
graph.resetAllModules()
@@ -258,6 +259,12 @@ proc connectToNextFreePort(server: Socket, host: string): Port =
type
ThreadParams = tuple[port: Port; address: string]
proc replStdinSingleCmd(line: string) =
requests.send line
toStdout()
echo ""
flushFile(stdout)
proc replStdin(x: ThreadParams) {.thread.} =
if gEmitEof:
echo DummyEof
@@ -271,10 +278,11 @@ proc replStdin(x: ThreadParams) {.thread.} =
echo Help
var line = ""
while readLineFromStdin("> ", line):
requests.send line
toStdout()
echo ""
flushFile(stdout)
replStdinSingleCmd(line)
proc replCmdline(x: ThreadParams) {.thread.} =
replStdinSingleCmd(x.address)
requests.send "quit"
proc replTcp(x: ThreadParams) {.thread.} =
var server = newSocket()
@@ -313,6 +321,7 @@ proc replEpc(x: ThreadParams) {.thread.} =
let port = connectToNextFreePort(server, "localhost")
server.listen()
echo port
stdout.flushFile()
var client = newSocket()
# Wait for connection
@@ -461,92 +470,6 @@ proc mainThread(graph: ModuleGraph; cache: IdentCache) =
var
inputThread: Thread[ThreadParams]
proc serveStdin(graph: ModuleGraph; cache: IdentCache) {.deprecated.} =
if gEmitEof:
echo DummyEof
while true:
let line = readLine(stdin)
execCmd line, graph, cache
echo DummyEof
flushFile(stdout)
else:
echo Help
var line = ""
while readLineFromStdin("> ", line):
execCmd line, graph, cache
echo ""
flushFile(stdout)
proc serveTcp(graph: ModuleGraph; cache: IdentCache) {.deprecated.} =
var server = newSocket()
server.bindAddr(gPort, gAddress)
var inp = "".TaintedString
server.listen()
while true:
var stdoutSocket = newSocket()
msgs.writelnHook = proc (line: string) =
stdoutSocket.send(line & "\c\L")
accept(server, stdoutSocket)
stdoutSocket.readLine(inp)
execCmd inp.string, graph, cache
stdoutSocket.send("\c\L")
stdoutSocket.close()
proc serveEpc(server: Socket; graph: ModuleGraph; cache: IdentCache) {.deprecated.} =
var client = newSocket()
# Wait for connection
accept(server, client)
if gLogging:
for it in searchPaths:
logStr(it)
msgs.writelnHook = proc (line: string) = logStr(line)
while true:
var
sizeHex = ""
size = 0
messageBuffer = ""
checkSanity(client, sizeHex, size, messageBuffer)
let
message = parseSexp($messageBuffer)
epcAPI = message[0].getSymbol
case epcAPI:
of "call":
let
uid = message[1].getNum
args = message[3]
gIdeCmd = parseIdeCmd(message[2].getSymbol)
case gIdeCmd
of ideChk:
setVerbosity(1)
# Use full path because other emacs plugins depends it
gListFullPaths = true
incl(gGlobalOptions, optIdeDebug)
var hints_or_errors = ""
sendEpc(hints_or_errors, string, msgs.writelnHook)
of ideSug, ideCon, ideDef, ideUse, ideDus, ideOutline, ideHighlight:
setVerbosity(0)
var suggests: seq[Suggest] = @[]
sendEpc(suggests, Suggest, suggestionResultHook)
else: discard
of "methods":
returnEpc(client, message[1].getNum, listEPC())
of "epc-error":
stderr.writeline("recieved epc error: " & $messageBuffer)
raise newException(IOError, "epc error")
else:
let errMessage = case epcAPI
of "return", "return-error":
"no return expected"
else:
"unexpected call: " & epcAPI
raise newException(EUnexpectedCommand, errMessage)
proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
clearPasses()
registerPass verbosePass
@@ -556,9 +479,6 @@ proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
isServing = true
wantMainModule()
add(searchPaths, options.libpath)
#if gProjectFull.len != 0:
# current path is always looked first for modules
# prependStr(searchPaths, gProjectPath)
# do not stop after the first error:
msgs.gErrorMax = high(int)
@@ -573,32 +493,13 @@ proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
of mstdin: createThread(inputThread, replStdin, (gPort, gAddress))
of mtcp: createThread(inputThread, replTcp, (gPort, gAddress))
of mepc: createThread(inputThread, replEpc, (gPort, gAddress))
of mcmdline: createThread(inputThread, replCmdline,
(gPort, "sug \"" & options.gProjectFull & "\":" & gAddress))
mainThread(graph, cache)
joinThread(inputThread)
close(requests)
close(results)
when false:
case gMode
of mstdin:
compileProject(graph, cache)
#modules.gFuzzyGraphChecking = false
serveStdin(graph, cache)
of mtcp:
# until somebody accepted the connection, produce no output (logging is too
# slow for big projects):
msgs.writelnHook = proc (msg: string) = discard
compileProject(graph, cache)
#modules.gFuzzyGraphChecking = false
serveTcp(graph, cache)
of mepc:
var server = newSocket()
let port = connectToNextFreePort(server, "localhost")
server.listen()
echo port
compileProject(graph, cache)
serveEpc(server, graph, cache)
proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
var p = parseopt.initOptParser(cmd)
while true:
@@ -614,6 +515,10 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
gAddress = p.val
gMode = mtcp
of "stdin": gMode = mstdin
of "cmdline":
gMode = mcmdline
suggestVersion = 2
gAddress = p.val
of "epc":
gMode = mepc
gVerbosity = 0 # Port number gotta be first.
@@ -678,12 +583,6 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
graph.suggestMode = true
mainCommand(graph, cache)
when false:
proc quitCalled() {.noconv.} =
writeStackTrace()
addQuitProc(quitCalled)
condsyms.initDefines()
defineSymbol "nimsuggest"
handleCmdline(newIdentCache(), newConfigRef())

View File

@@ -233,22 +233,25 @@ proc runEpcTest(filename: string): int =
let outp = p.outputStream
let inp = p.inputStream
var report = ""
var a = newStringOfCap(120)
#var a = newStringOfCap(120)
try:
# read the port number:
if outp.readLine(a):
let port = parseInt(a)
var socket = newSocket()
socket.connect("localhost", Port(port))
for req, resp in items(s.script):
if not runCmd(req, s.dest):
socket.sendEpcStr(req)
let sx = parseSexp(socket.recvEpc())
if not req.startsWith("mod "):
let answer = sexpToAnswer(sx)
doReport(filename, answer, resp, report)
else:
raise newException(ValueError, "cannot read port number")
#discard outp.readLine(a)
var i = 0
while not osproc.hasData(p) and i < 100:
os.sleep(50)
inc i
let a = outp.readAll().strip()
let port = parseInt(a)
var socket = newSocket()
socket.connect("localhost", Port(port))
for req, resp in items(s.script):
if not runCmd(req, s.dest):
socket.sendEpcStr(req)
let sx = parseSexp(socket.recvEpc())
if not req.startsWith("mod "):
let answer = sexpToAnswer(sx)
doReport(filename, answer, resp, report)
finally:
close(p)
if report.len > 0:
@@ -302,7 +305,9 @@ proc main() =
for x in walkFiles(getAppDir() / "tests/t*.nim"):
echo "Test ", x
let xx = expandFilename x
failures += runTest(xx)
when not defined(windows):
# XXX Windows IO redirection seems bonkers:
failures += runTest(xx)
failures += runEpcTest(xx)
if failures > 0:
quit 1