Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,116 changes: 102 additions & 1,014 deletions package-lock.json

Large diffs are not rendered by default.

27 changes: 1 addition & 26 deletions pythonFiles/completion.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -208,16 +208,6 @@ def _serialize_completions(self, script, identifier=None, prefix=''):
_completion['snippet'] = '%s=$1$0' % name
_completion['text'] = name
_completion['displayText'] = name
if self.show_doc_strings:
try:
_completion['description'] = signature.docstring()
_completion['raw_docstring'] = signature.docstring(raw=True)
except Exception:
_completion['description'] = ''
_completion['raw_docstring'] = ''
else:
_completion['description'] = self._generate_signature(
signature)
_completions.append(_completion)

try:
Expand All@@ -227,22 +217,11 @@ def _serialize_completions(self, script, identifier=None, prefix=''):
except :
completions = []
for completion in completions:
if self.show_doc_strings:
try:
description = completion.docstring()
except Exception:
description = ''
else:
description = self._generate_signature(completion)

try:
rawDocstring = completion.docstring(raw=True)
_completion = {
'text': completion.name,
'type': self._get_definition_type(completion),
'raw_type': completion.type,
'description': description,
'raw_docstring': rawDocstring,
'rightLabel': self._additional_info(completion)
}
except Exception:
Expand All@@ -252,11 +231,7 @@ def _serialize_completions(self, script, identifier=None, prefix=''):
if c['text'] == _completion['text']:
c['type'] = _completion['type']
c['raw_type'] = _completion['raw_type']
if len(c['description']) == 0 and len(c['raw_docstring']) == 0:
c['description'] = _completion['description']
c['raw_docstring'] = _completion['description']



if any([c['text'].split('=')[0] == _completion['text']
for c in _completions]):
# ignore function arguments we already have
Expand Down
2 changes: 1 addition & 1 deletion src/client/common/configSettings.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,7 +124,7 @@ export interface ITerminalSettings {
launchArgs: string[];
}

function isTestExecution(): boolean {
export function isTestExecution(): boolean {
// tslint:disable-next-line:interface-name no-string-literal
return process.env['VSC_PYTHON_CI_TEST'] === '1';
}
Expand Down
27 changes: 0 additions & 27 deletions src/client/jedi/parsers/CompletionParser.ts

This file was deleted.

71 changes: 0 additions & 71 deletions src/client/jedi/parsers/HoverParser.ts

This file was deleted.

5 changes: 2 additions & 3 deletions src/client/languageServices/jediProxyFactory.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
import { Disposable, Uri, workspace } from 'vscode';
import { JediProxy, JediProxyHandler, ICommandResult } from '../providers/jediProxy';
import { ICommandResult, JediProxy, JediProxyHandler } from '../providers/jediProxy';

export class JediFactory implements Disposable {
private disposables: Disposable[];
Expand All@@ -20,8 +20,7 @@ export class JediFactory implements Disposable {
if (!workspacePath) {
if (Array.isArray(workspace.workspaceFolders) && workspace.workspaceFolders.length > 0) {
workspacePath = workspace.workspaceFolders[0].uri.fsPath;
}
else {
} else {
workspacePath = __dirname;
}
}
Expand Down
83 changes: 23 additions & 60 deletions src/client/providers/completionProvider.ts
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,39 @@
'use strict';

import * as vscode from 'vscode';
import { Position, ProviderResult, SnippetString, Uri } from 'vscode';
import { PythonSettings } from '../common/configSettings';
import { Tokenizer } from '../language/tokenizer';
import { TokenType } from '../language/types';
import { isTestExecution } from '../common/configSettings';
import { JediFactory } from '../languageServices/jediProxyFactory';
import { captureTelemetry } from '../telemetry';
import { COMPLETION } from '../telemetry/constants';
import { extractSignatureAndDocumentation } from './jediHelpers';
import * as proxy from './jediProxy';
import { CompletionSource } from './completionSource';

export class PythonCompletionItemProvider implements vscode.CompletionItemProvider {
private completionSource: CompletionSource;

public constructor(private jediFactory: JediFactory) { }
private static parseData(data: proxy.ICompletionResult, resource: Uri): vscode.CompletionItem[] {
if (data && data.items.length > 0) {
return data.items.map(item => {
const sigAndDocs = extractSignatureAndDocumentation(item);
const completionItem = new vscode.CompletionItem(item.text);
completionItem.kind = item.type;
completionItem.documentation = sigAndDocs[1].length === 0 ? item.description : sigAndDocs[1];
completionItem.detail = sigAndDocs[0].split(/\r?\n/).join('');
if (PythonSettings.getInstance(resource).autoComplete.addBrackets === true &&
(item.kind === vscode.SymbolKind.Function || item.kind === vscode.SymbolKind.Method)) {
completionItem.insertText = new SnippetString(item.text).appendText('(').appendTabstop().appendText(')');
}

// ensure the built in memebers are at the bottom
completionItem.sortText = (completionItem.label.startsWith('__') ? 'z' : (completionItem.label.startsWith('_') ? 'y' : '__')) + completionItem.label;
return completionItem;
});
}
return [];
constructor(jediFactory: JediFactory) {
this.completionSource = new CompletionSource(jediFactory);
}

@captureTelemetry(COMPLETION)
public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): ProviderResult<vscode.CompletionItem[]> {
if (position.character <= 0) {
return Promise.resolve([]);
}
const filename = document.fileName;
const lineText = document.lineAt(position.line).text;
if (lineText.match(/^\s*\/\//)) {
return Promise.resolve([]);
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
Promise<vscode.CompletionItem[]> {
const items = await this.completionSource.getVsCodeCompletionItems(document, position, token);
if (isTestExecution()) {
for (let i = 0; i < Math.min(3, items.length); i += 1) {
items[i] = await this.resolveCompletionItem(items[i], token);
}
}
// Suppress completion inside string and comments
if (this.isPositionInsideStringOrComment(document, position)) {
return Promise.resolve([]);
}
const type = proxy.CommandType.Completions;
const columnIndex = position.character;

const source = document.getText();
const cmd: proxy.ICommand<proxy.ICommandResult> = {
command: type,
fileName: filename,
columnIndex: columnIndex,
lineIndex: position.line,
source: source
};

return this.jediFactory.getJediProxyHandler<proxy.ICompletionResult>(document.uri).sendCommand(cmd, token).then(data => {
return PythonCompletionItemProvider.parseData(data, document.uri);
});
return items;
}

private isPositionInsideStringOrComment(document: vscode.TextDocument, position: vscode.Position): boolean {
const tokenizeTo = position.translate(1, 0);
const text = document.getText(new vscode.Range(new Position(0, 0), tokenizeTo));
const t = new Tokenizer();
const tokens = t.Tokenize(text);
const index = tokens.getItemContaining(document.offsetAt(position));
return index >= 0 && (tokens[index].TokenType === TokenType.String || tokens[index].TokenType === TokenType.Comment);
public async resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken): Promise<vscode.CompletionItem> {
if (!item.documentation) {
const itemInfos = await this.completionSource.getDocumentation(item, token);
if (itemInfos && itemInfos.length > 0) {
item.detail = itemInfos[0].detail;
item.documentation = itemInfos[0].documentation;
}
}
return item;
}
}
Loading