Skip to content

Commit 3c17f4b

Browse files
Merge pull request #110 from ManuelHentschel/helpViewer
Help viewer
2 parents f173ebd + 4ebedb7 commit 3c17f4b

File tree

10 files changed

+87
-32
lines changed

10 files changed

+87
-32
lines changed

.vscode/tasks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"label": "Package and install Extension",
1818
"type": "shell",
1919
"problemMatcher": [],
20-
"command": "vsce package -o rdebugger.vsix && code --install-extension rdebugger.vsix --force",
20+
"command": "vsce package -o ${workspaceFolderBasename}.vsix && code --install-extension ${workspaceFolderBasename}.vsix --force",
2121
"group": {
2222
"kind": "build",
2323
"isDefault": true

package.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@
228228
"default": true,
229229
"markdownDescription": "Whether to attach a modified `load_all()` function (requries pkgload, direct calls to `pkgload::load_all()` are not affected)."
230230
},
231+
"overwriteHelp": {
232+
"type": "boolean",
233+
"default": true,
234+
"markdownDescription": "Whether to register a new S3 print method for `help_files_with_topic` to use the help panel from vscode-R."
235+
},
231236
"setBreakpointsInPackages": {
232237
"type": "boolean",
233238
"default": false,
@@ -410,12 +415,5 @@
410415
"semver": "^7.3.2",
411416
"tree-kill": "^1.2.2",
412417
"winreg": "^1.2.4"
413-
},
414-
"definitions": {
415-
"testDefinition": {
416-
"type": "string",
417-
"default": "testDefault",
418-
"description": "testDescription"
419-
}
420418
}
421419
}

src/debugAdapter.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ import { DebugRuntime } from './debugRuntime';
1414
import { DebugProtocol } from 'vscode-debugprotocol';
1515
import { InitializeRequest } from './debugProtocolModifications';
1616
import { config, getVSCodePackageVersion } from './utils';
17+
import { RExtension, HelpPanel } from './rExtensionApi';
1718

1819
import * as vscode from 'vscode';
1920

2021
import * as log from 'loglevel';
2122
const logger = log.getLogger("DebugSession");
22-
logger.setLevel(config().get<log.LogLevelDesc>('logLevelSession', 'INFO'));
23+
logger.setLevel(config().get<log.LogLevelDesc>('logLevelSession', 'SILENT'));
2324

2425

2526
function logMessage(message: DebugProtocol.ProtocolMessage){
@@ -46,9 +47,9 @@ export class DebugAdapter implements vscode.DebugAdapter {
4647
private runtime: DebugRuntime; // actually handles requests etc. that are not forwarded
4748
private disconnectTimeout: number = config().get<number>('timeouts.startup', 1000);
4849

49-
constructor() {
50+
constructor(helpPanel?: HelpPanel) {
5051
// construct R runtime
51-
this.runtime = new DebugRuntime();
52+
this.runtime = new DebugRuntime(helpPanel);
5253

5354
// setup event handler
5455
this.runtime.on('protocolMessage', (message: DebugProtocol.ProtocolMessage) => {
@@ -119,7 +120,7 @@ export class DebugAdapter implements vscode.DebugAdapter {
119120
case 'disconnect':
120121
// kill R process after timeout, in case it doesn't quit successfully
121122
setTimeout(()=>{
122-
console.log('killing R...');
123+
logger.info('killing R...');
123124
this.runtime.killR();
124125
}, this.disconnectTimeout);
125126
dispatchToR = true;

src/debugProtocolModifications.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22

33
import { DebugProtocol } from 'vscode-debugprotocol';
4+
// @ts-ignore
45
import * as VsCode from 'vscode';
56
// import { DebugProtocol } from './debugProtocol';
67

@@ -43,12 +44,14 @@ export interface DebugConfiguration extends VsCode.DebugConfiguration {
4344
overwriteStr?: boolean;
4445
overwriteSource?: boolean;
4546
overwriteLoadAll?: boolean;
47+
overwriteHelp?: boolean;
4648
splitOverwrittenOutput?: boolean;
4749

4850
// custom events/requests/capabilities:
4951
supportsWriteToStdinEvent?: boolean;
5052
supportsShowingPromptRequest?: boolean;
5153
supportsStdoutReading?: boolean;
54+
supportsHelpViewer?: boolean;
5255
ignoreFlowControl?: boolean;
5356

5457
useCustomSocket?: boolean;
@@ -145,6 +148,15 @@ export interface CustomEvent extends DebugProtocol.Event {
145148
}
146149
}
147150

151+
// Request help panel
152+
export interface ViewHelpEvent extends CustomEvent {
153+
body: ViewHelpBody;
154+
}
155+
export interface ViewHelpBody {
156+
reason: "viewHelp";
157+
requestPath: string;
158+
}
159+
148160
// Indicate that VS-Code should write a given text to R's stdin
149161
export interface WriteToStdinEvent extends CustomEvent {
150162
body: WriteToStdinBody;

src/debugRuntime.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import { RSession } from './rSession';
88
import { DebugProtocol } from 'vscode-debugprotocol';
99
import * as MDebugProtocol from './debugProtocolModifications';
1010
import { explainRPackage, PackageVersionInfo } from './installRPackage';
11+
import { RExtension, HelpPanel } from './rExtensionApi';
1112

1213
const { Subject } = require('await-notify');
1314

1415
import * as log from 'loglevel';
1516
const logger = log.getLogger("DebugRuntime");
16-
logger.setLevel(config().get<log.LogLevelDesc>('logLevelRuntime', 'info'));
17+
logger.setLevel(config().get<log.LogLevelDesc>('logLevelRuntime', 'SILENT'));
1718

1819

1920
export type LineHandler = (line: string, from: DataSource, isFullLine: boolean) => string;
@@ -46,6 +47,8 @@ export class DebugRuntime extends EventEmitter {
4647
// The rSession used to run the code
4748
public rSession: RSession;
4849

50+
readonly helpPanel: HelpPanel;
51+
4952
// // state info about the R session
5053
// R session
5154
private rSessionStartup = new Subject(); // used to wait for R session to start
@@ -70,8 +73,9 @@ export class DebugRuntime extends EventEmitter {
7073
private writeOnPrompt: WriteOnPrompt[] = [];
7174

7275
// constructor
73-
constructor() {
76+
constructor(helpPanel?: HelpPanel) {
7477
super();
78+
this.helpPanel = helpPanel;
7579
}
7680

7781
public async initializeRequest(response: DebugProtocol.InitializeResponse, args: MDebugProtocol.InitializeRequestArguments, request: MDebugProtocol.InitializeRequest) {
@@ -387,7 +391,7 @@ export class DebugRuntime extends EventEmitter {
387391
this.writeToStdin(wop.text);
388392
this.writeOnPrompt.unshift(wop);
389393
} else{
390-
console.log('invalid wop');
394+
logger.error('invalid writeOnPrompt entry');
391395
}
392396
} else {
393397
const cmdListen = this.rStrings.packageName + `::.vsc.listenForJSON(timeout = -1)`;
@@ -444,6 +448,8 @@ export class DebugRuntime extends EventEmitter {
444448
if(json.event === 'custom'){
445449
if(json.body.reason === "writeToStdin"){
446450
this.handleWriteToStdinEvent(json.body);
451+
} else if(json.body.reason === "viewHelp" && json.body.requestPath){
452+
this.helpPanel.showHelpForPath(json.body.requestPath);
447453
}
448454
logger.info("event: " + json.event, json.body);
449455
} else{

src/extension.ts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,35 @@ import {
1111
import { updateRPackage } from './installRPackage';
1212
import { trackTerminals, TerminalHandler } from './terminals';
1313

14-
let terminalHandler: TerminalHandler;
14+
import { RExtension, HelpPanel } from './rExtensionApi';
15+
1516
import * as fs from 'fs';
1617
import * as path from 'path';
1718

1819

1920
// this method is called when the extension is activated
2021
export async function activate(context: vscode.ExtensionContext) {
2122

22-
terminalHandler = new TerminalHandler();
23+
const rExtension = vscode.extensions.getExtension<RExtension>('ikuyadeu.r');
24+
25+
let rHelpPanel: HelpPanel = undefined;
26+
27+
if(rExtension){
28+
const api = await rExtension.activate();
29+
if(api){
30+
rHelpPanel = api.helpPanel;
31+
}
32+
}
33+
34+
const supportsHelpViewer = !!rHelpPanel;
35+
36+
const terminalHandler = new TerminalHandler();
2337
const port = await terminalHandler.portPromise;
2438

39+
context.subscriptions.push(terminalHandler);
40+
2541
// register configuration resolver
26-
const resolver = new DebugConfigurationResolver(port);
42+
const resolver = new DebugConfigurationResolver(port, 'localhost', supportsHelpViewer);
2743
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('R-Debugger', resolver));
2844

2945
// register dynamic configuration provider
@@ -35,7 +51,7 @@ export async function activate(context: vscode.ExtensionContext) {
3551
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('R-Debugger', initialProvider, DebugConfigurationProviderTriggerKind.Initial));
3652

3753
// register the debug adapter descriptor provider
38-
const factory = new DebugAdapterDescriptorFactory();
54+
const factory = new DebugAdapterDescriptorFactory(rHelpPanel);
3955
context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('R-Debugger', factory));
4056

4157
if(vscode.workspace.getConfiguration('rdebugger').get<boolean>('trackTerminals', false)){
@@ -48,18 +64,18 @@ export async function activate(context: vscode.ExtensionContext) {
4864
}
4965

5066
// this method is called when the extension is deactivated
51-
export function deactivate() {
52-
// close connections opened by terminalHandler
53-
if(terminalHandler){
54-
terminalHandler.close();
55-
}
56-
}
67+
export function deactivate() {}
5768

5869
class DebugAdapterDescriptorFactory implements vscode.DebugAdapterDescriptorFactory {
70+
helpPanel?: HelpPanel;
71+
72+
constructor(helpPanel?: HelpPanel){
73+
this.helpPanel = helpPanel;
74+
}
5975
createDebugAdapterDescriptor(session: vscode.DebugSession): ProviderResult<vscode.DebugAdapterDescriptor> {
6076
const config = session.configuration;
6177
if(config.request === 'launch'){
62-
return new vscode.DebugAdapterInlineImplementation(new DebugAdapter());
78+
return new vscode.DebugAdapterInlineImplementation(new DebugAdapter(this.helpPanel));
6379
} else if(config.request === 'attach'){
6480
const port: number = config.port || 18721;
6581
const host: string = config.host || 'localhost';
@@ -190,10 +206,12 @@ class DebugConfigurationResolver implements vscode.DebugConfigurationProvider {
190206

191207
readonly customPort: number;
192208
readonly customHost: string;
209+
readonly supportsHelpViewer: boolean;
193210

194-
constructor(customPort: number, customHost: string = 'localhost') {
211+
constructor(customPort: number, customHost: string = 'localhost', supportsHelpViewer: boolean = false) {
195212
this.customPort = customPort;
196213
this.customHost = customHost;
214+
this.supportsHelpViewer = supportsHelpViewer;
197215
}
198216

199217
resolveDebugConfiguration(folder: WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: CancellationToken): ProviderResult<StrictDebugConfiguration> {
@@ -250,6 +268,9 @@ class DebugConfigurationResolver implements vscode.DebugConfigurationProvider {
250268
config.supportsStdoutReading = true;
251269
config.supportsWriteToStdinEvent = true;
252270
config.supportsShowingPromptRequest = true;
271+
// set to true if not specified. necessary since its default in vscDebugger is FALSE:
272+
config.overwriteHelp = config.overwriteHelp ?? true;
273+
config.overwriteHelp = config.overwriteHelp && this.supportsHelpViewer; // check if helpview available
253274
} else if (config.request === 'attach'){
254275
// communication info with TerminalHandler():
255276
config.customPort = config.customPort ?? this.customPort;

src/rExtensionApi.d.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
3+
4+
export declare class RExtension {
5+
helpPanel: HelpPanel;
6+
}
7+
8+
9+
export interface HelpPanel {
10+
dispose(): void;
11+
showHelpForInput(): Promise<boolean>;
12+
showHelpForFunctionName(fncName: string, pkgName: string): void;
13+
showHelpForPath(requestPath: string): void;
14+
}
15+
16+
17+

src/rSession.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class RSession {
3232

3333

3434
constructor(){
35-
logger.setLevel(config().get<log.LogLevelDesc>('logLevelRSession', 'silent'));
35+
logger.setLevel(config().get<log.LogLevelDesc>('logLevelRSession', 'SILENT'));
3636
};
3737

3838
public async startR(

src/terminals.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { WriteToStdinEvent, WriteToStdinBody } from './debugProtocolModification
3232
import { config, getPortNumber } from './utils';
3333

3434
const logger = log.getLogger("DebugRuntime");
35-
logger.setLevel(config().get<log.LogLevelDesc>('logLevelTerminals', 'INFO'));
35+
logger.setLevel(config().get<log.LogLevelDesc>('logLevelTerminals', 'SILENT'));
3636

3737
let doTrackTerminals: boolean = false;
3838

@@ -106,8 +106,8 @@ export class TerminalHandler {
106106
this.portPromise = portPromise;
107107
}
108108

109-
public close(){
110-
console.log('Closing custom server connections');
109+
public dispose(){
110+
logger.info('Closing custom server connections');
111111
this.lineCache.forEach((_, socket) => {
112112
socket.destroy();
113113
});

test/R/.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@
3838
"splitOverwrittenOutput": true
3939
}
4040
]
41-
}
41+
}

0 commit comments

Comments
 (0)