140
140
onExit* : OnExitCallback
141
141
projectFiles* : Table [string , Project ]
142
142
openFiles* : Table [string , NlsFileInfo ]
143
- idleOpenFiles* : Table [string , NlsFileInfo ] # We close the file when its inactive and store it here.
143
+ idleOpenFiles* : Table [string , NlsFileInfo ]
144
+ # We close the file when its inactive and store it here.
144
145
workspaceConfiguration* : Future [JsonNode ]
145
146
prevWorkspaceConfiguration* : Future [JsonNode ]
146
147
inlayHintsRefreshRequest* : Future [JsonNode ]
@@ -306,7 +307,7 @@ proc getWorkspaceConfiguration*(
306
307
proc getAndWaitForWorkspaceConfiguration * (
307
308
ls: LanguageServer
308
309
): Future [NlsConfig ] {.async .} =
309
- try :
310
+ try :
310
311
let conf = await ls.workspaceConfiguration
311
312
return parseWorkspaceConfiguration (conf)
312
313
except CatchableError as ex:
@@ -384,11 +385,11 @@ proc getLspStatus*(ls: LanguageServer): NimLangServerStatus {.raises: [].} =
384
385
result .projectErrors = ls.projectErrors
385
386
386
387
proc sendStatusChanged * (ls: LanguageServer ) {.raises : [].} =
387
- let status = %* ls.getLspStatus ()
388
+ let status = %* ls.getLspStatus ()
388
389
if status != ls.lastStatusSent:
389
390
ls.notify (" extension/statusUpdate" , status)
390
391
ls.lastStatusSent = status
391
-
392
+
392
393
proc addProjectFileToPendingRequest * (
393
394
ls: LanguageServer , id: uint , uri: string
394
395
) {.async .} =
@@ -606,7 +607,7 @@ proc toUtf16Pos*(suggest: Suggest, ls: LanguageServer): Suggest =
606
607
result .column = pos.get ()
607
608
608
609
proc toUtf16Pos * (
609
- suggest: SuggestInlayHint , ls: LanguageServer , uri: string
610
+ suggest: SuggestInlayHint , ls: LanguageServer , uri: string
610
611
): SuggestInlayHint =
611
612
result = suggest
612
613
let pos = toUtf16Pos (ls, uri, suggest.line - 1 , suggest.column)
@@ -619,9 +620,10 @@ proc toUtf16Pos*(checkResult: CheckResult, ls: LanguageServer): CheckResult =
619
620
let pos = toUtf16Pos (ls, uri, checkResult.line - 1 , checkResult.column)
620
621
if pos.isSome:
621
622
result .column = pos.get ()
622
-
623
- for i in 0 ..< result .stacktrace.len:
624
- let stPos = toUtf16Pos (ls, uri, result .stacktrace[i].line - 1 , result .stacktrace[i].column)
623
+
624
+ for i in 0 ..< result .stacktrace.len:
625
+ let stPos =
626
+ toUtf16Pos (ls, uri, result .stacktrace[i].line - 1 , result .stacktrace[i].column)
625
627
if stPos.isSome:
626
628
result .stacktrace[i].column = stPos.get ()
627
629
@@ -642,7 +644,7 @@ proc toDiagnostic(suggest: Suggest): Diagnostic =
642
644
textStart = doc.find ('\' ' )
643
645
textEnd = doc.rfind ('\' ' )
644
646
endColumn =
645
- if textStart >= 0 and textEnd >= 0 :
647
+ if textStart >= 0 and textEnd > textStart :
646
648
column + utf16Len (doc[textStart + 1 ..< textEnd])
647
649
else :
648
650
column + 1
@@ -677,7 +679,12 @@ proc toDiagnostic(checkResult: CheckResult): Diagnostic =
677
679
let node =
678
680
%* {
679
681
" uri" : pathToUri (checkResult.file),
680
- " range" : range (checkResult.line - 1 , max (0 , checkResult.column), checkResult.line - 1 , max (0 , endColumn)),
682
+ " range" : range (
683
+ checkResult.line - 1 ,
684
+ max (0 , checkResult.column),
685
+ checkResult.line - 1 ,
686
+ max (0 , endColumn),
687
+ ),
681
688
" severity" :
682
689
case checkResult.severity
683
690
of " Error" : DiagnosticSeverity .Error .int
@@ -688,21 +695,24 @@ proc toDiagnostic(checkResult: CheckResult): Diagnostic =
688
695
" message" : checkResult.msg,
689
696
" source" : " nim" ,
690
697
" code" : " nim check" ,
691
- }
698
+ }
692
699
return node.to (Diagnostic )
693
700
694
- proc sendDiagnostics * (ls: LanguageServer , diagnostics: seq [Suggest ] | seq [CheckResult ], path: string ) =
701
+ proc sendDiagnostics * (
702
+ ls: LanguageServer , diagnostics: seq [Suggest ] | seq [CheckResult ], path: string
703
+ ) =
695
704
trace " Sending diagnostics" , count = diagnostics.len, path = path
696
705
let params =
697
- PublishDiagnosticsParams %*
698
- {" uri" : pathToUri (path), " diagnostics" : diagnostics.map (x => x.toUtf16Pos (ls).toDiagnostic)}
706
+ PublishDiagnosticsParams %* {
707
+ " uri" : pathToUri (path),
708
+ " diagnostics" : diagnostics.map (x => x.toUtf16Pos (ls).toDiagnostic),
709
+ }
699
710
ls.notify (" textDocument/publishDiagnostics" , % params)
700
711
if diagnostics.len != 0 :
701
712
ls.filesWithDiags.incl path
702
713
else :
703
714
ls.filesWithDiags.excl path
704
715
705
-
706
716
proc warnIfUnknown * (
707
717
ls: LanguageServer , ns: Nimsuggest , uri: string , projectFile: string
708
718
): Future [void ] {.async , gcsafe .} =
@@ -728,35 +738,31 @@ proc getNimsuggestInner(ls: LanguageServer, uri: string): Future[Nimsuggest] {.a
728
738
ls.createOrRestartNimsuggest (projectFile, uri)
729
739
# Wait a bit to allow nimsuggest to start
730
740
await sleepAsync (10 )
731
-
741
+
732
742
# Check multiple times with small delays
733
743
var attempts = 0
734
744
const maxAttempts = 10
735
745
while attempts < maxAttempts:
736
746
if projectFile in ls.projectFiles:
737
747
ls.lastNimsuggest = ls.projectFiles[projectFile].ns
738
748
return await ls.projectFiles[projectFile].ns
739
-
749
+
740
750
inc attempts
741
751
if attempts < maxAttempts:
742
752
await sleepAsync (100 )
743
- debug " Waiting for nimsuggest to initialize" ,
744
- uri = uri,
745
- projectFile = projectFile,
746
- attempt = attempts
747
-
753
+ debug " Waiting for nimsuggest to initialize" ,
754
+ uri = uri, projectFile = projectFile, attempt = attempts
755
+
748
756
debug " Failed to get nimsuggest after waiting" , uri = uri, projectFile = projectFile
749
757
return nil
750
758
751
759
proc tryGetNimsuggest * (
752
760
ls: LanguageServer , uri: string
753
- ): Future [Option [Nimsuggest ]] {.raises :[], gcsafe .}
761
+ ): Future [Option [Nimsuggest ]] {.raises : [], gcsafe .}
754
762
755
- proc checkFile * (ls: LanguageServer , uri: string ): Future [void ] {.raises :[], gcsafe .}
763
+ proc checkFile * (ls: LanguageServer , uri: string ): Future [void ] {.raises : [], gcsafe .}
756
764
757
- proc didCloseFile * (
758
- ls: LanguageServer , uri: string
759
- ): Future [void ] {.async , gcsafe .} =
765
+ proc didCloseFile * (ls: LanguageServer , uri: string ): Future [void ] {.async , gcsafe .} =
760
766
debug " Closed the following document:" , uri = uri
761
767
762
768
if ls.openFiles[uri].changed:
@@ -774,7 +780,9 @@ proc makeIdleFile*(
774
780
ls.idleOpenFiles[uri] = file
775
781
ls.openFiles.del (uri)
776
782
777
- proc getProjectFile * (fileUri: string , ls: LanguageServer ): Future [string ] {.raises :[], gcsafe .}
783
+ proc getProjectFile * (
784
+ fileUri: string , ls: LanguageServer
785
+ ): Future [string ] {.raises : [], gcsafe .}
778
786
779
787
proc didOpenFile * (
780
788
ls: LanguageServer , textDocument: TextDocumentItem
@@ -785,9 +793,13 @@ proc didOpenFile*(
785
793
file = open (ls.uriStorageLocation (uri), fmWrite)
786
794
projectFileFuture = getProjectFile (uriToPath (uri), ls)
787
795
788
- ls.openFiles[uri] =
789
- NlsFileInfo (projectFile: projectFileFuture, changed: false , fingerTable: @ [], textDocument: textDocument)
790
-
796
+ ls.openFiles[uri] = NlsFileInfo (
797
+ projectFile: projectFileFuture,
798
+ changed: false ,
799
+ fingerTable: @ [],
800
+ textDocument: textDocument,
801
+ )
802
+
791
803
if uri in ls.idleOpenFiles:
792
804
ls.idleOpenFiles.del (uri)
793
805
@@ -817,29 +829,28 @@ proc didOpenFile*(
817
829
ls.showMessage (fmt " Opening {uri}" , MessageType .Info )
818
830
819
831
proc tryGetNimsuggest * (
820
- ls: LanguageServer , uri: string
832
+ ls: LanguageServer , uri: string
821
833
): Future [Option [Nimsuggest ]] {.async .} =
822
-
823
834
if uri in ls.idleOpenFiles:
824
835
let idleFile = ls.idleOpenFiles[uri]
825
836
await didOpenFile (ls, idleFile.textDocument)
826
837
827
838
if uri notin ls.openFiles:
828
839
return none (NimSuggest )
829
-
840
+
830
841
var retryCount = 0
831
842
const maxRetries = 3
832
843
while retryCount < maxRetries:
833
844
let ns = await getNimsuggestInner (ls, uri)
834
845
if not ns.isNil:
835
846
return some ns
836
-
847
+
837
848
# If nimsuggest is nil, wait a bit and retry
838
849
inc retryCount
839
850
if retryCount < maxRetries:
840
851
debug " Nimsuggest not ready, retrying..." , uri = uri, attempt = retryCount
841
- await sleepAsync (10000 * retryCount) # Exponential backoff
842
-
852
+ await sleepAsync (10000 * retryCount) # Exponential backoff
853
+
843
854
debug " Nimsuggest not found after retries" , uri = uri
844
855
return none (NimSuggest )
845
856
@@ -848,11 +859,12 @@ proc checkProject*(ls: LanguageServer, uri: string): Future[void] {.async, gcsaf
848
859
return
849
860
let conf = await ls.getAndWaitForWorkspaceConfiguration ()
850
861
let useNimCheck = conf.useNimCheck.get (USE_NIM_CHECK_BY_DEFAULT )
851
-
862
+
852
863
let nimPath = getNimPath (conf)
853
864
854
865
if useNimCheck and nimPath.isSome:
855
- proc getFilePath (c: CheckResult ): string = c.file
866
+ proc getFilePath (c: CheckResult ): string =
867
+ c.file
856
868
857
869
let token = fmt " Checking {uri}"
858
870
ls.workDoneProgressCreate (token)
@@ -863,13 +875,13 @@ proc checkProject*(ls: LanguageServer, uri: string): Future[void] {.async, gcsaf
863
875
return
864
876
let diagnostics = await nimCheck (uriToPath (uri), nimPath.get)
865
877
let filesWithDiags = diagnostics.map (r => r.file).toHashSet
866
-
878
+
867
879
ls.progress (token, " end" )
868
-
880
+
869
881
debug " Found diagnostics" , file = filesWithDiags
870
882
for (path, diags) in groupBy (diagnostics, getFilePath):
871
883
ls.sendDiagnostics (diags, path)
872
-
884
+
873
885
# clean files with no diags
874
886
for path in ls.filesWithDiags:
875
887
if not filesWithDiags.contains path:
@@ -927,8 +939,6 @@ proc checkProject*(ls: LanguageServer, uri: string): Future[void] {.async, gcsaf
927
939
debug " Running delayed check project..." , uri = uri
928
940
traceAsyncErrors ls.checkProject (uri)
929
941
930
-
931
-
932
942
proc onErrorCallback (args: (LanguageServer , string ), project: Project ) =
933
943
let
934
944
ls = args[0 ]
@@ -977,7 +987,7 @@ proc createOrRestartNimsuggest*(
977
987
ls.createOrRestartNimsuggest (projectFile, uri)
978
988
ls.sendStatusChanged ()
979
989
errorCallback = partial (onErrorCallback, (ls, uri))
980
-
990
+
981
991
debug " Creating new nimsuggest project" , projectFile = projectFile
982
992
let projectNext = waitFor createNimsuggest (
983
993
projectFile,
@@ -990,12 +1000,12 @@ proc createOrRestartNimsuggest*(
990
1000
configuration.logNimsuggest.get (false ),
991
1001
configuration.exceptionHintsEnabled,
992
1002
)
993
-
1003
+
994
1004
if projectFile in ls.projectFiles:
995
1005
var project = ls.projectFiles[projectFile]
996
1006
project.stop ()
997
1007
ls.projectFiles[projectFile] = projectNext
998
-
1008
+
999
1009
projectNext.ns.addCallback do (fut: Future [Nimsuggest ]):
1000
1010
if fut.failed:
1001
1011
let msg = fut.error.msg
@@ -1011,9 +1021,8 @@ proc createOrRestartNimsuggest*(
1011
1021
fut.read ().openFiles.incl uri
1012
1022
ls.sendStatusChanged ()
1013
1023
except CatchableError as ex:
1014
- error " Failed to create/restart nimsuggest" ,
1015
- projectFile = projectFile,
1016
- error = ex.msg
1024
+ error " Failed to create/restart nimsuggest" ,
1025
+ projectFile = projectFile, error = ex.msg
1017
1026
1018
1027
proc restartAllNimsuggestInstances (ls: LanguageServer ) =
1019
1028
debug " Restarting all nimsuggest instances"
@@ -1130,8 +1139,6 @@ proc getProjectFile*(fileUri: string, ls: LanguageServer): Future[string] {.asyn
1130
1139
1131
1140
debug " getProjectFile " , project = result , fileUri = fileUri
1132
1141
1133
-
1134
-
1135
1142
proc checkFile * (ls: LanguageServer , uri: string ): Future [void ] {.async .} =
1136
1143
let conf = await ls.getAndWaitForWorkspaceConfiguration ()
1137
1144
let useNimCheck = conf.useNimCheck.get (USE_NIM_CHECK_BY_DEFAULT )
@@ -1186,7 +1193,7 @@ proc removeIdleNimsuggests*(ls: LanguageServer) {.async.} =
1186
1193
for project in toStop:
1187
1194
debug " Removing idle nimsuggest" , project = project.file
1188
1195
project.errorCallback = none (ProjectCallback )
1189
-
1196
+
1190
1197
let ns = await project.ns
1191
1198
for uri in ns.openFiles:
1192
1199
debug " Removing idle nimsuggest open file" , uri = uri
@@ -1208,4 +1215,3 @@ proc tick*(ls: LanguageServer): Future[void] {.async.} =
1208
1215
except CatchableError as ex:
1209
1216
error " Error in tick" , msg = ex.msg
1210
1217
writeStacktrace (ex)
1211
-
0 commit comments