Skip to content

Commit

Permalink
Expands arc when hovering a proc (#275)
Browse files Browse the repository at this point in the history
* expands arc when hovering a proc

* only expand arc in definitions

* Fixes an issue where nim processes accumulates and expands stop working. Adds clarification on hover

* Fixes an issue with expandMacro
  • Loading branch information
jmgomez authored Jan 7, 2025
1 parent d5e033a commit 9aeb8d3
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 12 deletions.
23 changes: 14 additions & 9 deletions nimcheck.nim
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,18 @@ proc nimCheck*(filePath: string, nimPath: string): Future[seq[CheckResult]] {.as
stderrHandle = AsyncProcess.Pipe,
stdoutHandle = AsyncProcess.Pipe,
)
let res = await process.waitForExit(InfiniteDuration)
# debug "nimCheck exit", res = res
var output = ""
if res == 0: #Nim check return 0 if there are no errors but we still need to check for hints and warnings
output = string.fromBytes(process.stdoutStream.read().await)
else:
output = string.fromBytes(process.stderrStream.read().await)
try:
let res = await process.waitForExit(15.seconds)
# debug "nimCheck exit", res = res
var output = ""
if res == 0: #Nim check return 0 if there are no errors but we still need to check for hints and warnings
output = string.fromBytes(process.stdoutStream.read().await)
else:
output = string.fromBytes(process.stderrStream.read().await)

let lines = output.splitLines()
parseCheckResults(lines)
let lines = output.splitLines()
parseCheckResults(lines)

finally:
if not process.isNil:
discard process.kill()
86 changes: 86 additions & 0 deletions nimexpand.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import std/[strutils]
import regex
import chronos, chronos/asyncproc
import stew/[byteutils]
import chronicles
import protocol/types
import utils
import suggestapi
import std/[strscans, strformat]


proc extractMacroExpansion*(output: string, targetLine: int): string =
var start = false
for line in output.split({'\n', '\r'}):
if line.len == 0: continue
debug "extractMacroExpansion", line = line, condMet = &".nim({targetLine}," in line
if &".nim({targetLine}," in line:
start = true
elif &".nim" in line and start:
break
if start:
result.add line & "\n"

if result.len > 0:
let macroStart = result.find("macro: ")
if macroStart != -1:
result = result.substr(macroStart + "macro: ".len)
result = result.replace("[ExpandMacro]", "")

proc nimExpandMacro*(nimPath: string, suggest: Suggest, filePath: string): Future[string] {.async.} =
let
macroName = suggest.qualifiedPath[suggest.qualifiedPath.len - 1]
line = suggest.line
debug "nimExpandMacro", macroName = macroName, line = line, filePath = filePath
debug "Executing ", cmd = &"nim c --expandMacro:{macroName} {filePath}"
let process = await startProcess(
nimPath,
arguments = @["c", "--expandMacro:" & macroName] & @[filePath],
options = {UsePath, StdErrToStdOut},
stdoutHandle = AsyncProcess.Pipe,
)
try:
let res = await process.waitForExit(10.seconds)
let output = string.fromBytes(process.stdoutStream.read().await)
result = extractMacroExpansion(output, line)
finally:
if not process.isNil:
discard process.kill()


proc extractArcExpansion*(output: string, procName: string): string =
var start = false
let cond = &"--expandArc: {procName}"
for line in output.splitLines:
# debug "extractArcExpansion", line = line, condMet = cond in line
if cond in line:
start = true
elif &"-- end of expandArc" in line and start:
break
if start:
result.add line & "\n"

if result.len > 0:
result = result.replace(cond, "").strip()


proc nimExpandArc*(nimPath: string, suggest: Suggest, filePath: string): Future[string] {.async.} =
let procName = suggest.qualifiedPath[suggest.qualifiedPath.len - 1]
debug "nimExpandArc", procName = procName, filePath = filePath
let process = await startProcess(
nimPath,
arguments = @["c", &"--expandArc:{procName}", "--compileOnly"] & @[filePath],
options = {UsePath, StdErrToStdOut},
stdoutHandle = AsyncProcess.Pipe,
)
try:
let res = await process.waitForExit(10.seconds)
let output = string.fromBytes(process.stdoutStream.read().await)
result = extractArcExpansion(output, procName)
# debug "nimExpandArc", output = output, result = result
if result.len == 0:
result = &"#Couldnt expand arc for `{procName}`. Showing raw output instead (nimPath). \n"
result.add output
finally:
if not process.isNil:
discard process.kill()
21 changes: 18 additions & 3 deletions routes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import
json_serialization,
std/[strscans, times, json, parseutils, strutils],
ls,
stew/[byteutils]

stew/[byteutils],
nimexpand,
nimcheck
proc getNphPath(): Option[string] =
let path = findExe "nph"
if path == "":
Expand Down Expand Up @@ -402,8 +403,22 @@ proc hover*(
if suggest.symkind == "skMacro":
let expanded = await nimsuggest.get
.expand(uriToPath(uri), ls.uriToStash(uri), suggest.line, suggest.column)
if expanded.len > 0:
if expanded.len > 0 and expanded[0].doc != "":
# debug "Expanded macro", expanded = expanded[0].doc
content.add MarkedStringOption %* {"language": "nim", "value": expanded[0].doc}
else:
# debug "Couldnt expand the macro. Trying with nim expand", suggest = suggest[]
let nimPath = ls.getWorkspaceConfiguration().await.getNimPath()
if nimPath.isSome:
let expanded = await nimExpandMacro(nimPath.get, suggest, uriToPath(uri))
content.add MarkedStringOption %* {"language": "nim", "value": expanded}
if suggest.section == ideDef and suggest.symkind in ["skProc"]:
debug "#Expanding arc", suggest = suggest[]
let nimPath = ls.getWorkspaceConfiguration().await.getNimPath()
if nimPath.isSome:
let expanded = await nimExpandArc(nimPath.get, suggest, uriToPath(uri))
let arcContent = "#Expanded arc \n" & expanded
content.add MarkedStringOption %* {"language": "nim", "value": arcContent}
return some(Hover(
contents: some(%content),
range: some(toLabelRange(suggest.toUtf16Pos(ls))),
Expand Down

0 comments on commit 9aeb8d3

Please sign in to comment.