()
| 40 | } |
| 41 | |
| 42 | public launchRHelpServer(): ChildProcessWithPort{ |
| 43 | const lim = '---vsc---'; |
| 44 | const portRegex = new RegExp(`.*${lim}(.*)${lim}.*`, 'ms'); |
| 45 | |
| 46 | const newPackageRegex = new RegExp('NEW_PACKAGES'); |
| 47 | |
| 48 | // starts the background help server and waits forever to keep the R process running |
| 49 | const scriptPath = extensionContext.asAbsolutePath('R/help/helpServer.R'); |
| 50 | const args = [ |
| 51 | '--silent', |
| 52 | '--no-echo', |
| 53 | '--no-save', |
| 54 | '--no-restore', |
| 55 | '-e', |
| 56 | 'base::source(base::commandArgs(TRUE))', |
| 57 | '--args', |
| 58 | scriptPath |
| 59 | ]; |
| 60 | const cpOptions = { |
| 61 | cwd: this.cwd, |
| 62 | env: { |
| 63 | ...process.env, |
| 64 | VSCR_LIB_PATHS: getRLibPaths(), |
| 65 | VSCR_LIM: lim, |
| 66 | VSCR_USE_RENV_LIB_PATH: config().get<boolean>('useRenvLibPath') ? 'TRUE' : 'FALSE' |
| 67 | }, |
| 68 | }; |
| 69 | |
| 70 | const childProcess: ChildProcessWithPort = spawn(this.rPath, args, cpOptions); |
| 71 | |
| 72 | let str = ''; |
| 73 | // promise containing the port number of the process (or 0) |
| 74 | const portPromise = new Promise<number>((resolve) => { |
| 75 | childProcess.stdout?.on('data', (data) => { |
| 76 | try{ |
| 77 | // eslint-disable-next-line |
| 78 | str += data.toString(); |
| 79 | } catch(e){ |
| 80 | resolve(0); |
| 81 | } |
| 82 | if(portRegex.exec(str)){ |
| 83 | resolve(Number(str.replace(portRegex, '$1'))); |
| 84 | str = str.replace(portRegex, ''); |
| 85 | } |
| 86 | if(newPackageRegex.exec(str)){ |
| 87 | this.pkgListener?.(); |
| 88 | str = str.replace(newPackageRegex, ''); |
| 89 | } |
| 90 | }); |
| 91 | childProcess.on('close', () => { |
| 92 | resolve(0); |
| 93 | }); |
| 94 | }); |
| 95 | |
| 96 | const exitHandler = () => { |
| 97 | childProcess.port = 0; |
| 98 | }; |
| 99 | childProcess.on('exit', exitHandler); |
no test coverage detected