Skip to content

Commit

Permalink
Make dirty files unique per source file (#13)
Browse files Browse the repository at this point in the history
* dirty files are per nimsuggest instance per source file
* upon close dirty files are cleaned up
  • Loading branch information
RSDuck authored Nov 12, 2020
1 parent ae78ded commit 9b99f44
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 26 deletions.
1 change: 0 additions & 1 deletion src/nimvscode/jsNodeFs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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.}
Expand Down
2 changes: 1 addition & 1 deletion src/nimvscode/nimBuild.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
3 changes: 2 additions & 1 deletion src/nimvscode/nimDeclaration.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,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):
Expand Down
3 changes: 2 additions & 1 deletion src/nimvscode/nimHover.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
15 changes: 9 additions & 6 deletions src/nimvscode/nimIndexer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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] = @[]
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/nimvscode/nimOutline.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion src/nimvscode/nimReferences.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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] = @[]
Expand Down
3 changes: 2 additions & 1 deletion src/nimvscode/nimRename.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
3 changes: 2 additions & 1 deletion src/nimvscode/nimSignature.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/nimvscode/nimSuggest.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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()):
Expand Down
12 changes: 11 additions & 1 deletion src/nimvscode/nimSuggestExec.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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]]()
Expand All @@ -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())
Expand Down Expand Up @@ -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:
Expand All @@ -209,6 +212,8 @@ proc getNimSuggestProcess(nimProject:ProjectFileInfo):Future[NimSuggestProcessDe
)
reject(msg.toJs())
)

fs.mkdirSync(getDirtyFileFolder(process.pid))
)
return nimSuggestProcessCache[projectPath]

Expand All @@ -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] = @[]
Expand All @@ -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(
Expand Down
38 changes: 28 additions & 10 deletions src/nimvscode/nimUtils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import jscore
import strformat

import sequtils
import hashes

type
ProjectFileInfo* = ref object
Expand Down Expand Up @@ -167,8 +168,35 @@ 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.nim")
)
Expand Down Expand Up @@ -203,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():
Expand Down

0 comments on commit 9b99f44

Please sign in to comment.