forked from conwnet/github1s
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhover.ts
More file actions
122 lines (96 loc) · 4.29 KB
/
Copy pathhover.ts
File metadata and controls
122 lines (96 loc) · 4.29 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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* @file HoverProvider
* @author netcon
*/
import * as vscode from 'vscode';
import router from '@/router';
import { getSourcegraphUrl } from '@/helpers/urls';
import { adapterManager } from '@/adapters';
const getSemanticMarkdownSuffix = (sourcegraphUrl: String) => `
---
[Semantic](https://docs.sourcegraph.com/code_intelligence/explanations/precise_code_intelligence) result provided by [Sourcegraph](${sourcegraphUrl})
`;
const getSearchBasedMarkdownSuffix = (sourcegraphUrl: String) => `
---
[Search-based](https://docs.sourcegraph.com/code_intelligence/explanations/precise_code_intelligence) result provided by [Sourcegraph](${sourcegraphUrl})
`;
export class GitHub1sHoverProvider implements vscode.HoverProvider, vscode.Disposable {
private static instance: GitHub1sHoverProvider | null = null;
private readonly disposable: vscode.Disposable;
private constructor() {}
public static getInstance(): GitHub1sHoverProvider {
if (GitHub1sHoverProvider.instance) {
return GitHub1sHoverProvider.instance;
}
return (GitHub1sHoverProvider.instance = new GitHub1sHoverProvider());
}
dispose() {
this.disposable?.dispose();
}
async getSearchBasedHover(
document: vscode.TextDocument,
position: vscode.Position,
symbol: string
): Promise<string | null> {
const { line, character } = position;
const authority = document.uri.authority || (await router.getAuthority());
const [repo, ref] = authority.split('+').filter(Boolean);
const dataSource = await adapterManager.getCurrentAdapter().resolveDataSource();
const requestParams = [repo, ref, document.uri.path, line, character, symbol] as const;
const definitions = await dataSource.provideSymbolDefinitions(...requestParams);
if (!definitions.length) {
return null;
}
// use the information of first definition as hover context
const target = definitions[0];
const isSameRepo = !target.scope || (target.scope.scheme === document.uri.scheme && target.scope.repo === repo);
// if the definition target and the searched symbol is in the same
// repository, just replace the `document.uri.path` with targetPath
const targetFileUri = isSameRepo
? document.uri.with({ path: `/${target.path}` })
: vscode.Uri.parse('').with({
scheme: target.scope?.scheme,
authority: `${target.scope?.repo}+${target.scope?.ref}`,
path: `/${target.path}`,
});
// open corresponding file with target
const textDocument = await vscode.workspace.openTextDocument(targetFileUri);
// get the content in `[range.start.line - 2, range.end.line + 2]` lines
const startPosition = new vscode.Position(Math.max(0, target.range.start.line - 2), 0);
// eslint-disable-next-line max-len
const endPosition = textDocument.lineAt(Math.min(textDocument.lineCount - 1, target.range.end.line + 2)).range.end;
const codeText = textDocument.getText(new vscode.Range(startPosition, endPosition));
return `\`\`\`${textDocument.languageId}\n${codeText}\n\`\`\``;
}
async provideHover(
document: vscode.TextDocument,
position: vscode.Position,
_token: vscode.CancellationToken
): Promise<vscode.Hover | null> {
const symbolRange = document.getWordRangeAtPosition(position);
const symbol = symbolRange ? document.getText(symbolRange) : '';
if (!symbol) {
return null;
}
const authority = document.uri.authority || (await router.getAuthority());
const [repo, ref] = authority.split('+').filter(Boolean);
const path = document.uri.path;
const { line, character } = position;
// get the sourcegraph url for current symbol
const sourcegraphUrl = getSourcegraphUrl(repo, ref, path, line, character);
const requestParams = [repo, ref, path, line, character, symbol] as const;
// get the hover result based on search
const searchBasedMardownPromise = this.getSearchBasedHover(document, position, symbol);
// get the hover result based on sourcegraph lsif
const dataSource = await adapterManager.getCurrentAdapter().resolveDataSource();
const symbolHover = await dataSource.provideSymbolHover(...requestParams);
const markdown = symbolHover ? symbolHover.markdown : await searchBasedMardownPromise;
if (!markdown) {
return null;
}
const suffixMarkdown = symbolHover
? getSemanticMarkdownSuffix(sourcegraphUrl)
: getSearchBasedMarkdownSuffix(sourcegraphUrl);
return new vscode.Hover(markdown + suffixMarkdown);
}
}