|
| 1 | +import * as vscode from 'vscode'; |
| 2 | +import { ExtensionContext, SymbolKind, SymbolInformation } from 'vscode'; |
| 3 | +import * as Locate from '../locate/locate'; |
| 4 | + |
| 5 | +export function registerIntellisenseProvider(ctx: ExtensionContext) { |
| 6 | + // for locate: if it's a project, use the root, othewise, don't bother |
| 7 | + if (vscode.workspace.getConfiguration('ruby').intellisense == 'rubyLocate') { |
| 8 | + if (vscode.workspace.rootPath) { |
| 9 | + const refreshLocate = () => { |
| 10 | + let progressOptions = { location: vscode.ProgressLocation.Window, title: 'Indexing Ruby source files' }; |
| 11 | + vscode.window.withProgress(progressOptions, () => locate.walk()); |
| 12 | + }; |
| 13 | + const settings: any = vscode.workspace.getConfiguration("ruby.locate") || {}; |
| 14 | + let locate = new Locate(vscode.workspace.rootPath, settings); |
| 15 | + refreshLocate(); |
| 16 | + ctx.subscriptions.push(vscode.commands.registerCommand('ruby.reloadProject', refreshLocate)); |
| 17 | + |
| 18 | + const watch = vscode.workspace.createFileSystemWatcher(settings.include); |
| 19 | + watch.onDidChange(uri => locate.parse(uri.fsPath)); |
| 20 | + watch.onDidCreate(uri => locate.parse(uri.fsPath)); |
| 21 | + watch.onDidDelete(uri => locate.rm(uri.fsPath)); |
| 22 | + const locationConverter = match => new vscode.Location(vscode.Uri.file(match.file), new vscode.Position(match.line, match.char)); |
| 23 | + const defProvider = { |
| 24 | + provideDefinition: (doc, pos) => { |
| 25 | + const txt = doc.getText(doc.getWordRangeAtPosition(pos)); |
| 26 | + return locate.find(txt).then(matches => matches.map(locationConverter)); |
| 27 | + } |
| 28 | + }; |
| 29 | + ctx.subscriptions.push(vscode.languages.registerDefinitionProvider(['ruby', 'erb'], defProvider)); |
| 30 | + const symbolKindTable = { |
| 31 | + class: () => SymbolKind.Class, |
| 32 | + module: () => SymbolKind.Module, |
| 33 | + method: symbolInfo => symbolInfo.name === 'initialize' ? SymbolKind.Constructor : SymbolKind.Method, |
| 34 | + classMethod: () => SymbolKind.Method, |
| 35 | + }; |
| 36 | + const defaultSymbolKind = symbolInfo => { |
| 37 | + console.warn(`Unknown symbol type: ${symbolInfo.type}`); |
| 38 | + return SymbolKind.Variable; |
| 39 | + }; |
| 40 | + // NOTE: Workaround for high CPU usage on IPC (channel.onread) when too many symbols returned. |
| 41 | + // For channel.onread see issue like this: https://github.com/Microsoft/vscode/issues/6026 |
| 42 | + const numOfSymbolLimit = 3000; |
| 43 | + const symbolsConverter = matches => matches.slice(0, numOfSymbolLimit).map(match => { |
| 44 | + const symbolKind = (symbolKindTable[match.type] || defaultSymbolKind)(match); |
| 45 | + return new SymbolInformation(match.name, symbolKind, match.containerName, locationConverter(match)); |
| 46 | + }); |
| 47 | + const docSymbolProvider = { |
| 48 | + provideDocumentSymbols: (document, token) => { |
| 49 | + return locate.listInFile(document.fileName).then(symbolsConverter); |
| 50 | + } |
| 51 | + }; |
| 52 | + ctx.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(['ruby', 'erb'], docSymbolProvider)); |
| 53 | + const workspaceSymbolProvider = { |
| 54 | + provideWorkspaceSymbols: (query, token) => { |
| 55 | + return locate.query(query).then(symbolsConverter); |
| 56 | + } |
| 57 | + }; |
| 58 | + ctx.subscriptions.push(vscode.languages.registerWorkspaceSymbolProvider(workspaceSymbolProvider)); |
| 59 | + } else { |
| 60 | + var rubyLocateUnavailable = () => { |
| 61 | + vscode.window.showInformationMessage('There is not an open workspace for rubyLocate to reload.'); |
| 62 | + }; |
| 63 | + ctx.subscriptions.push(vscode.commands.registerCommand('ruby.reloadProject', rubyLocateUnavailable)); |
| 64 | + } |
| 65 | + } else { |
| 66 | + var rubyLocateDisabled = () => { |
| 67 | + vscode.window.showInformationMessage('The `ruby.intellisense` configuration is not set to use rubyLocate.') |
| 68 | + }; |
| 69 | + ctx.subscriptions.push(vscode.commands.registerCommand('ruby.reloadProject', rubyLocateDisabled)); |
| 70 | + } |
| 71 | +} |
0 commit comments