@@ -38,6 +38,7 @@ import { CollectionResult } from "pyright-internal-node/dist/packages/pyright-in
3838import { ParseFileResults } from "pyright-internal-node/dist/packages/pyright-internal/src/parser/parser" ;
3939
4040import { PyrightLanguageProvider } from "./python/PyrightLanguageProvider" ;
41+ import { RLanguageProvider } from "./r/RLanguageProvider" ;
4142import { CodeZoneManager } from "./sas/CodeZoneManager" ;
4243import { LanguageServiceProvider , legend } from "./sas/LanguageServiceProvider" ;
4344import type { LibCompleteItem } from "./sas/SyntaxDataProvider" ;
@@ -52,13 +53,15 @@ interface DocumentInfo {
5253export const runServer = (
5354 connection : Connection ,
5455 _pyrightLanguageProvider : PyrightLanguageProvider ,
56+ _rLanguageProvider : RLanguageProvider ,
5557) => {
5658 const documentPool : Record < string , DocumentInfo > = { } ;
5759
5860 let supportSASGetLibList = false ;
5961 let registeredAdvancedCapabilities = false ;
6062
6163 _pyrightLanguageProvider . setSasLspProvider ( getLanguageService ) ;
64+ _rLanguageProvider . setSasLspProvider ( getLanguageService ) ;
6265
6366 connection . onInitialize ( ( params ) => {
6467 if (
@@ -117,7 +120,10 @@ export const runServer = (
117120 return result ;
118121 } ) ;
119122
120- connection . onInitialized ( ( ) => _pyrightLanguageProvider . onInitialized ( ) ) ;
123+ connection . onInitialized ( ( ) => {
124+ _pyrightLanguageProvider . onInitialized ( ) ;
125+ _rLanguageProvider . onInitialized ( ) ;
126+ } ) ;
121127
122128 connection . onRequest ( SemanticTokensRequest . type , ( params ) => {
123129 syncIfDocChange ( params . textDocument . uri ) ;
@@ -136,6 +142,9 @@ export const runServer = (
136142 async python ( pyrightLanguageService ) {
137143 return await pyrightLanguageService . onHover ( params , token ) ;
138144 } ,
145+ async r ( rLanguageService ) {
146+ return await rLanguageService . onHover ( params , token ) ;
147+ } ,
139148 } ) ;
140149 } ) ;
141150
@@ -216,6 +225,53 @@ export const runServer = (
216225 }
217226 return completionList ;
218227 } ,
228+ async r ( rLanguageService ) {
229+ const completionList = await rLanguageService . onCompletion (
230+ params ,
231+ token ,
232+ ) ;
233+ if ( completionList ) {
234+ for ( const item of completionList . items ) {
235+ if ( ! item . data ) {
236+ item . data = { } ;
237+ }
238+ item . data . _languageService = "r" ;
239+ item . data . _uri = params . textDocument . uri ;
240+ }
241+
242+ if (
243+ params . context ?. triggerKind === CompletionTriggerKind . Invoked ||
244+ params . context ?. triggerKind ===
245+ CompletionTriggerKind . TriggerForIncompleteCompletions
246+ ) {
247+ const doc = documentPool [ params . textDocument . uri ] . document ;
248+ const line = doc . getText ( {
249+ start : {
250+ line : params . position . line ,
251+ character : 0 ,
252+ } ,
253+ end : params . position ,
254+ } ) ;
255+ if ( ! / \W / . test ( line . trimStart ( ) ) ) {
256+ const item = {
257+ kind : CompletionItemKind . Keyword ,
258+ data : {
259+ _languageService : "sas" ,
260+ _uri : params . textDocument . uri ,
261+ } ,
262+ } ;
263+ if (
264+ completionList . items . findIndex (
265+ ( item ) => item . label === "endsubmit" ,
266+ ) === - 1
267+ ) {
268+ completionList . items . push ( { ...item , label : "endsubmit" } ) ;
269+ }
270+ }
271+ }
272+ }
273+ return completionList ;
274+ } ,
219275 } ) ;
220276 } ) ;
221277
@@ -231,6 +287,11 @@ export const runServer = (
231287 completionItem ,
232288 token ,
233289 ) ;
290+ } else if ( lang === "r" ) {
291+ return await _rLanguageProvider . onCompletionResolve (
292+ completionItem ,
293+ token ,
294+ ) ;
234295 }
235296 return completionItem ;
236297 } ) ;
@@ -329,6 +390,14 @@ export const runServer = (
329390 // eslint-disable-next-line @typescript-eslint/no-explicit-any
330391 ) ) as any ;
331392 } ,
393+ async r ( rLanguageService ) {
394+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
395+ return ( await rLanguageService . onSignatureHelp (
396+ params ,
397+ token ,
398+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
399+ ) ) as any ;
400+ } ,
332401 } ) ;
333402 } ) ;
334403
@@ -350,12 +419,14 @@ export const runServer = (
350419 ) ;
351420 documentPool [ doc . uri ] = { document : doc , changed : false } ;
352421 await _pyrightLanguageProvider . onDidOpenTextDocument ( params ) ;
422+ await _rLanguageProvider . onDidOpenTextDocument ( params ) ;
353423 } ) ;
354424
355425 connection . onDidCloseTextDocument ( async ( params ) => {
356426 const uri = params . textDocument . uri ;
357427 delete documentPool [ uri ] ;
358428 await _pyrightLanguageProvider . onDidCloseTextDocument ( params ) ;
429+ await _rLanguageProvider . onDidCloseTextDocument ( params ) ;
359430 } ) ;
360431
361432 connection . onDidChangeTextDocument ( ( params ) => {
@@ -382,6 +453,9 @@ export const runServer = (
382453 async python ( pyrightLanguageService ) {
383454 return await pyrightLanguageService . onDefinition ( params , token ) ;
384455 } ,
456+ async r ( rLanguageService ) {
457+ return await rLanguageService . onDefinition ( params , token ) ;
458+ } ,
385459 } ) ;
386460 } ,
387461 ) ;
@@ -562,6 +636,7 @@ export const runServer = (
562636
563637 connection . onShutdown ( async ( token ) => {
564638 await _pyrightLanguageProvider . onShutdown ( token ) ;
639+ await _rLanguageProvider . onShutdown ( token ) ;
565640 } ) ;
566641
567642 // Listen on the connection
@@ -591,9 +666,11 @@ export const runServer = (
591666 python ?: (
592667 pyrightLanguageService : PyrightLanguageProvider ,
593668 ) => Promise < Ret > ;
669+ r ?: ( rLanguageService : RLanguageProvider ) => Promise < Ret > ;
594670 default ?: ( languageServices : {
595671 sasLanguageService : LanguageServiceProvider ;
596672 pythonLanguageService ?: PyrightLanguageProvider ;
673+ rLanguageService ?: RLanguageProvider ;
597674 } ) => Promise < Ret > ;
598675 } ,
599676 ) => {
@@ -627,6 +704,24 @@ export const runServer = (
627704 return await callbacks . default ( {
628705 sasLanguageService : languageService ,
629706 pythonLanguageService : _pyrightLanguageProvider ,
707+ rLanguageService : _rLanguageProvider ,
708+ } ) ;
709+ } else {
710+ return undefined ;
711+ }
712+ }
713+ if (
714+ symbol . name ?. toUpperCase ( ) === "PROC RLANG" &&
715+ codeZoneManager . getCurrentZone ( pos . line , pos . character ) ===
716+ CodeZoneManager . ZONE_TYPE . EMBEDDED_LANG
717+ ) {
718+ if ( callbacks . r ) {
719+ return await callbacks . r ( _rLanguageProvider ) ;
720+ } else if ( callbacks . default ) {
721+ return await callbacks . default ( {
722+ sasLanguageService : languageService ,
723+ pythonLanguageService : _pyrightLanguageProvider ,
724+ rLanguageService : _rLanguageProvider ,
630725 } ) ;
631726 } else {
632727 return undefined ;
@@ -640,6 +735,7 @@ export const runServer = (
640735 return await callbacks . default ( {
641736 sasLanguageService : languageService ,
642737 pythonLanguageService : _pyrightLanguageProvider ,
738+ rLanguageService : _rLanguageProvider ,
643739 } ) ;
644740 }
645741 {
@@ -660,11 +756,16 @@ export const runServer = (
660756
661757 const syncIfDocChange = ( uri : string ) => {
662758 const docInfo = documentPool [ uri ] ;
759+ if ( ! docInfo ) {
760+ // Document not in pool yet - this can happen if hover is triggered before onDidOpenTextDocument
761+ return ;
762+ }
663763 if ( ! docInfo . changed ) {
664764 return ;
665765 }
666766 docInfo . changed = false ;
667767 _pyrightLanguageProvider . addContentChange ( docInfo . document ) ;
768+ _rLanguageProvider . addContentChange ( docInfo . document ) ;
668769 } ;
669770
670771 const syncAllChangedDoc = ( ) => {
0 commit comments