mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 13:33:22 +00:00
nimsuggest supports prefix matching (first version)
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user