forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhoverProvider.ts
More file actions
108 lines (102 loc) · 4.61 KB
/
hoverProvider.ts
File metadata and controls
108 lines (102 loc) · 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
'use strict';
import * as vscode from 'vscode';
import * as proxy from './jediProxy';
import * as telemetryContracts from "../common/telemetryContracts";
import { highlightCode } from './jediHelpers';
import { EOL } from 'os';
export class PythonHoverProvider implements vscode.HoverProvider {
private jediProxyHandler: proxy.JediProxyHandler<proxy.IHoverResult>;
public constructor(context: vscode.ExtensionContext, jediProxy: proxy.JediProxy = null) {
this.jediProxyHandler = new proxy.JediProxyHandler(context, jediProxy);
}
private static parseData(data: proxy.IHoverResult, currentWord: string): vscode.Hover {
let results = [];
let capturedInfo: string[] = [];
data.items.forEach(item => {
let { description, signature } = item;
const rawSignature = signature;
switch (item.kind) {
case vscode.SymbolKind.Constructor:
case vscode.SymbolKind.Function:
case vscode.SymbolKind.Method: {
signature = 'def ' + signature;
break;
}
case vscode.SymbolKind.Class: {
signature = 'class ' + signature;
break;
}
default: {
signature = typeof item.text === 'string' && item.text.length > 0 ? item.text : currentWord;
}
}
if (item.docstring) {
let lines = item.docstring.split(EOL);
// If the docstring starts with the signature, then remove those lines from the docstring
if (lines.length > 0 && item.signature.indexOf(lines[0]) === 0) {
lines.shift();
let endIndex = lines.findIndex(line => item.signature.endsWith(line));
if (endIndex >= 0) {
lines = lines.filter((line, index) => index > endIndex);
}
}
if (lines.length > 0 && item.signature.startsWith(currentWord) && lines[0].startsWith(currentWord) && lines[0].endsWith(')')) {
lines.shift();
}
let descriptionWithHighlightedCode = highlightCode(lines.join(EOL));
let hoverInfo = '```python' + EOL + signature + EOL + '```' + EOL + descriptionWithHighlightedCode;
let key = signature + lines.join('');
// Sometimes we have duplicate documentation, one with a period at the end
if (capturedInfo.indexOf(key) >= 0 || capturedInfo.indexOf(key + '.') >= 0) {
return;
}
capturedInfo.push(key);
capturedInfo.push(key + '.');
results.push(hoverInfo);
return;
}
if (item.description) {
let descriptionWithHighlightedCode = highlightCode(item.description);
let hoverInfo = '```python' + EOL + signature + EOL + '```' + EOL + descriptionWithHighlightedCode;
let lines = item.description.split(EOL);
let key = signature + lines.join('');
// Sometimes we have duplicate documentation, one with a period at the end
if (capturedInfo.indexOf(key) >= 0 || capturedInfo.indexOf(key + '.') >= 0) {
return;
}
capturedInfo.push(key);
capturedInfo.push(key + '.');
results.push(hoverInfo);
}
});
return new vscode.Hover(results);
}
public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover> {
var filename = document.fileName;
if (document.lineAt(position.line).text.match(/^\s*\/\//)) {
return null;
}
if (position.character <= 0) {
return null;
}
var range = document.getWordRangeAtPosition(position);
if (!range || range.isEmpty) {
return null;
}
let word = document.getText(range);
var cmd: proxy.ICommand<proxy.IDefinitionResult> = {
command: proxy.CommandType.Hover,
fileName: filename,
columnIndex: range.end.character,
lineIndex: position.line
};
if (document.isDirty) {
cmd.source = document.getText();
}
const data = await this.jediProxyHandler.sendCommand(cmd, token);
if (!data || !data.items.length) {
return;
}
return PythonHoverProvider.parseData(data, word);
}
}