From 4e0bcd4673853c4369b47ae34f608c17067efde4 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Thu, 5 Nov 2020 16:54:29 +0100 Subject: [PATCH 1/2] make dirty files unique per source file --- src/nimvscode/nimUtils.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nimvscode/nimUtils.nim b/src/nimvscode/nimUtils.nim index 87123cc..9c084ec 100644 --- a/src/nimvscode/nimUtils.nim +++ b/src/nimvscode/nimUtils.nim @@ -11,6 +11,7 @@ import jscore import strformat import sequtils +import hashes type ProjectFileInfo* = ref object @@ -170,7 +171,7 @@ proc getProjectFileInfo*(filename:cstring):ProjectFileInfo = proc getDirtyFile*(doc:VscodeTextDocument):cstring = ## temporary file path of edited document var dirtyFilePath = path.normalize( - path.join(extensionContext.storagePath,"vscodenimdirty.nim") + path.join(extensionContext.storagePath,"vscodenimdirty" & $int(hash(doc.uri.fsPath)) & ".nim") ) fs.writeFileSync(dirtyFilePath, doc.getText()) return dirtyFilePath From c05cc7b2169e01b97e700a37ae915709e627aed7 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Wed, 11 Nov 2020 23:45:10 +0100 Subject: [PATCH 2/2] group dirty files per nimsuggest instance and clean everything up upon closing --- src/nimvscode/jsNodeFs.nim | 1 - src/nimvscode/nimBuild.nim | 2 +- src/nimvscode/nimDeclaration.nim | 3 ++- src/nimvscode/nimHover.nim | 3 ++- src/nimvscode/nimIndexer.nim | 15 +++++++----- src/nimvscode/nimOutline.nim | 2 +- src/nimvscode/nimReferences.nim | 3 ++- src/nimvscode/nimRename.nim | 3 ++- src/nimvscode/nimSignature.nim | 3 ++- src/nimvscode/nimSuggest.nim | 3 ++- src/nimvscode/nimSuggestExec.nim | 12 +++++++++- src/nimvscode/nimUtils.nim | 39 +++++++++++++++++++++++--------- 12 files changed, 62 insertions(+), 27 deletions(-) diff --git a/src/nimvscode/jsNodeFs.nim b/src/nimvscode/jsNodeFs.nim index 5ce08e5..08938b3 100644 --- a/src/nimvscode/jsNodeFs.nim +++ b/src/nimvscode/jsNodeFs.nim @@ -30,7 +30,6 @@ type proc existsSync*(fs:Fs, file:cstring):bool {.importcpp.} proc mkdirSync*(fs:Fs, file:cstring):void {.importcpp.} proc unlinkSync*(fs:Fs, file:cstring):void {.importcpp.} -proc removedirSync*(fs:Fs, file:cstring):void {.importcpp.} proc stat*(fs:Fs, file:cstring, cb:StatCallback):void {.importcpp.} proc statSync*(fs:Fs, file:cstring):FsStats {.importcpp.} proc lstatSync*(fs:Fs, file:cstring):FsStats {.importcpp.} diff --git a/src/nimvscode/nimBuild.nim b/src/nimvscode/nimBuild.nim index be39818..76f2d3a 100644 --- a/src/nimvscode/nimBuild.nim +++ b/src/nimvscode/nimBuild.nim @@ -189,7 +189,7 @@ proc check*(filename:cstring, nimConfig:VscodeWorkspaceConfiguration):Promise[se runningToolsPromises.add(newPromise(proc( resolve:proc(values:seq[CheckResult]), reject:proc(reason:JsObject) - ) = execNimSuggest(NimSuggestType.chk, filename, 0, 0, "").then( + ) = execNimSuggest(NimSuggestType.chk, filename, 0, 0, false).then( proc(items:seq[NimSuggestResult]) = if items.toJs().to(bool) and items.len > 0: resolve(parseNimsuggestErrors(items)) diff --git a/src/nimvscode/nimDeclaration.nim b/src/nimvscode/nimDeclaration.nim index 6240fec..ad3791e 100644 --- a/src/nimvscode/nimDeclaration.nim +++ b/src/nimvscode/nimDeclaration.nim @@ -19,7 +19,8 @@ proc provideDefinition*( doc.fileName, pos, position.character, - getDirtyFile(doc) + true, + doc.getText() ).then( proc(result:seq[NimSuggestResult]) = if(not result.isNull() and not result.isUndefined() and result.len > 0): diff --git a/src/nimvscode/nimHover.nim b/src/nimvscode/nimHover.nim index 704aad2..4d34052 100644 --- a/src/nimvscode/nimHover.nim +++ b/src/nimvscode/nimHover.nim @@ -18,7 +18,8 @@ proc provideHover*( doc.fileName, pos, position.character, - getDirtyFile(doc) + true, + doc.getText() ).then(proc(items:seq[NimSuggestResult]) = if(not items.isNull() and not items.isUndefined() and items.len > 0): var definition = items[items.len - 1] diff --git a/src/nimvscode/nimIndexer.nim b/src/nimvscode/nimIndexer.nim index 99f74b3..d45cdfc 100644 --- a/src/nimvscode/nimIndexer.nim +++ b/src/nimvscode/nimIndexer.nim @@ -55,20 +55,23 @@ proc vscodeKindFromNimSym(kind:cstring):VscodeSymbolKind = proc getFileSymbols*( file:cstring, - dirtyFile:cstring -):Future[seq[VscodeSymbolInformation]] {.async.} = + useDirtyFile:bool, + dirtyFileContent:cstring="" +): + Future[seq[VscodeSymbolInformation]] {.async.} = console.log( - "getFileSymbols - execnimsuggest - ", + "getFileSymbols - execnimsuggest - useDirtyFile", $(NimSuggestType.outline), file, - dirtyFile + useDirtyFile ) var items = await nimSuggestExec.execNimSuggest( NimSuggestType.outline, file, 0, 0, - dirtyFile + useDirtyFile, + dirtyFileContent ) var symbols:seq[VscodeSymbolInformation] = @[] @@ -102,7 +105,7 @@ proc indexFile(file:cstring) {.async.} = var timestamp = fs.statSync(file).mtime.getTime().toJs().to(cint) var doc = await findFile(file, timestamp) if doc.isNil(): - var infos = await getFileSymbols(file, "") + var infos = await getFileSymbols(file, false) if infos.isNull() or infos.len == 0: return diff --git a/src/nimvscode/nimOutline.nim b/src/nimvscode/nimOutline.nim index ef3cabd..00a02e1 100644 --- a/src/nimvscode/nimOutline.nim +++ b/src/nimvscode/nimOutline.nim @@ -12,7 +12,7 @@ proc provideDocumentSymbols( doc:VscodeTextDocument, token:VscodeCancellationToken ):Promise[seq[VscodeSymbolInformation]] = - return getFileSymbols(doc.filename, getDirtyFile(doc)) + return getFileSymbols(doc.filename, true, doc.getText()) type NimOutline* = ref object provideWorkspaceSymbols*:proc( diff --git a/src/nimvscode/nimReferences.nim b/src/nimvscode/nimReferences.nim index da70d59..157e8e1 100644 --- a/src/nimvscode/nimReferences.nim +++ b/src/nimvscode/nimReferences.nim @@ -18,7 +18,8 @@ proc provideReferences*( doc.fileName, pos, position.character, - getDirtyFile(doc) + true, + doc.getText() ).then( proc(results:seq[NimSuggestResult]) = var references: seq[VscodeLocation] = @[] diff --git a/src/nimvscode/nimRename.nim b/src/nimvscode/nimRename.nim index afd35b0..ceb9b34 100644 --- a/src/nimvscode/nimRename.nim +++ b/src/nimvscode/nimRename.nim @@ -18,7 +18,8 @@ proc provideRenameEdits*( doc.fileName, pos, position.character, - getDirtyFile(doc) + true, + doc.getText() ).then(proc (suggestions:seq[NimSuggestResult]) = var references = vscode.newWorkspaceEdit() if not suggestions.isNull() and not suggestions.isUndefined(): diff --git a/src/nimvscode/nimSignature.nim b/src/nimvscode/nimSignature.nim index 766987e..1466a70 100644 --- a/src/nimvscode/nimSignature.nim +++ b/src/nimvscode/nimSignature.nim @@ -74,7 +74,8 @@ proc provideSignatureHelp( filename, startPos, position.character, - getDirtyFile(doc) + true, + doc.getText() ).then(proc(items:seq[NimSuggestResult]) = var signatures = vscode.newSignatureHelp() var isModule = 0 diff --git a/src/nimvscode/nimSuggest.nim b/src/nimvscode/nimSuggest.nim index d202d15..46da361 100644 --- a/src/nimvscode/nimSuggest.nim +++ b/src/nimvscode/nimSuggest.nim @@ -73,7 +73,8 @@ proc provideCompletionItems*( filename, startPos, position.character, - getDirtyFile(doc) + true, + doc.getText() ).then(proc(items:seq[NimSuggestResult]) = var suggestions: seq[VscodeCompletionItem] = @[] if (not items.isNull() and not items.isUndefined()): diff --git a/src/nimvscode/nimSuggestExec.nim b/src/nimvscode/nimSuggestExec.nim index d11ae3e..98355f5 100644 --- a/src/nimvscode/nimSuggestExec.nim +++ b/src/nimvscode/nimSuggestExec.nim @@ -136,6 +136,7 @@ proc closeAllNimSuggestProcesses*():Promise[void] = console.log("Close all nimsuggest processes") for project in nimSuggestProcessCache.keys(): nimSuggestProcessCache[project].then(proc(desc:NimSuggestProcessDescription):void = + cleanupDirtyFileFolder(desc.process.pid) closeCachedProcess(desc) ) nimSuggestProcessCache = newJsAssoc[cstring, Promise[NimSuggestProcessDescription]]() @@ -146,6 +147,7 @@ proc closeNimSuggestProcess*(project:ProjectFileInfo) {.async.} = if process.toJs().to(bool): try: var desc = await process + cleanupDirtyFileFolder(desc.process.pid) closeCachedProcess(desc) except: console.log("closeNimSuggestProcess ignorable error", getCurrentException()) @@ -196,6 +198,7 @@ proc getNimSuggestProcess(nimProject:ProjectFileInfo):Future[NimSuggestProcessDe console.log("getNimSuggestProcess - stderr pid: ", process.pid, "data:", data.toString()) ) process.onClose(proc(code:cint, signal:cstring):void = + cleanupDirtyFileFolder(process.pid) var codeStr = if code.toJs().isNull(): "unknown" else: $(code) var msg = fmt"nimsuggest {process.pid} (args: {args.join("" "")}) closed with code: {codeStr} and signal: {signal}" if code != 0: @@ -209,6 +212,8 @@ proc getNimSuggestProcess(nimProject:ProjectFileInfo):Future[NimSuggestProcessDe ) reject(msg.toJs()) ) + + fs.mkdirSync(getDirtyFileFolder(process.pid)) ) return nimSuggestProcessCache[projectPath] @@ -217,7 +222,8 @@ proc execNimSuggest*( filename:cstring, line:cint, column:cint, - dirtyFile: cstring + useDirtyFile:bool, + dirtyFileContent:cstring="" ):Future[seq[NimSuggestResult]] {.async.} = var nimSuggestExec = getNimSuggestPath() var ret:seq[NimSuggestResult] = @[] @@ -240,6 +246,10 @@ proc execNimSuggest*( var desc = await getNimSuggestProcess(projectFile) var suggestCmd:cstring = $(suggestType) var isValidDesc = desc.toJs().to(bool) + var dirtyFile = cstring "" + + if useDirtyFile: + dirtyFile = getDirtyFile(desc.process.pid, filename, dirtyFileContent) if isValidDesc and desc.process.toJs().to(bool): trace( diff --git a/src/nimvscode/nimUtils.nim b/src/nimvscode/nimUtils.nim index 9c084ec..176a753 100644 --- a/src/nimvscode/nimUtils.nim +++ b/src/nimvscode/nimUtils.nim @@ -168,10 +168,37 @@ proc getProjectFileInfo*(filename:cstring):ProjectFileInfo = return project return projects[0] +proc removeDirSync*(p:cstring):void = + if fs.existsSync(p): + for entry in fs.readdirSync(p): + var curPath = path.resolve(p, entry) + if fs.lstatSync(curPath).isDirectory(): + removeDirSync(curPath) + else: + fs.unlinkSync(curPath) + fs.rmdirSync(p) + +proc getDirtyFileFolder*(nimsuggestPid:cint): cstring = + path.join(extensionContext.storagePath, "vscodenimdirty_" & $nimsuggestPid) + +proc cleanupDirtyFileFolder*(nimsuggestPid:cint) = + removeDirSync(getDirtyFileFolder(nimsuggestPid)) + +proc getDirtyFile*(nimsuggestPid:cint,filepath,content:cstring):cstring = + ## temporary file path of edited document + ## for each nimsuggest instance each file has a unique dirty file + var dirtyFilePath = path.normalize( + path.join(getDirtyFileFolder(nimsuggestPid), $int(hash(filepath)) & ".nim") + ) + fs.writeFileSync(dirtyFilePath, content) + return dirtyFilePath + proc getDirtyFile*(doc:VscodeTextDocument):cstring = ## temporary file path of edited document + ## returns always the same file, so it shouldn't + ## be used for nimsuggest, only nimpretty! var dirtyFilePath = path.normalize( - path.join(extensionContext.storagePath,"vscodenimdirty" & $int(hash(doc.uri.fsPath)) & ".nim") + path.join(extensionContext.storagePath,"vscodenimdirty.nim") ) fs.writeFileSync(dirtyFilePath, doc.getText()) return dirtyFilePath @@ -204,16 +231,6 @@ proc prepareConfig*():void = proc getProjects*():seq[ProjectFileInfo] = projects -proc removeDirSync*(p:cstring):void = - if fs.existsSync(p): - for entry in fs.readdirSync(p): - var curPath = path.resolve(p, entry) - if fs.lstatSync(curPath).isDirectory(): - removeDirSync(curPath) - else: - fs.unlinkSync(curPath) - fs.rmdirSync(p) - var channel:VscodeOutputChannel proc getOutputChannel*():VscodeOutputChannel = if channel.isNil():