Skip to content

Provide full signature help with highlighted parameter #416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Dec 15, 2017
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7675901
Basic tokenizer
Dec 1, 2017
eb42669
Fixed property names
Dec 1, 2017
2756974
Tests, round I
Dec 1, 2017
c2c1ced
Tests, round II
Dec 2, 2017
a108c96
merge master
Dec 3, 2017
14864a5
tokenizer test
Dec 4, 2017
0ed51d6
Remove temorary change
Dec 4, 2017
51b544c
Fix merge issue
Dec 4, 2017
3cd11e6
Merge conflict
Dec 4, 2017
82e0ad1
Merge conflict
Dec 4, 2017
9295c1a
Completion test
Dec 4, 2017
06eb1a5
Fix last line
Dec 4, 2017
e9db8e0
Fix javascript math
Dec 4, 2017
d12ca03
Merge master
Dec 5, 2017
d8ab041
Make test await for results
Dec 5, 2017
db75cd0
Add license headers
Dec 5, 2017
9ab2c47
Rename definitions to types
Dec 5, 2017
d587485
License headers
Dec 5, 2017
1da5e0a
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Dec 5, 2017
7668cee
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Dec 11, 2017
1ac4932
Fix typo in completion details (typo)
Dec 11, 2017
2aa5a6c
Fix hover test
Dec 12, 2017
5db31bd
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Dec 12, 2017
560d2af
Russian translations
Dec 13, 2017
c71024d
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Dec 13, 2017
31aa087
Update to better translation
Dec 13, 2017
593ae05
Fix typo
Dec 13, 2017
e6d69bb
#70 How to get all parameter info when filling in a function param list
Dec 13, 2017
b5a23d3
Fix #70 How to get all parameter info when filling in a function para…
Dec 14, 2017
cd200f7
Clean up
Dec 14, 2017
7c33228
Clean imports
Dec 14, 2017
c4a6b90
CR feedback
Dec 14, 2017
f85b848
Trim whitespace for test stability
Dec 14, 2017
37c210b
More tests
Dec 15, 2017
61a5650
Better handle no-parameters documentation
Dec 15, 2017
a10305e
Better handle ellipsis and Python3
Dec 15, 2017
11aaae2
Remove test change
Dec 15, 2017
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
50 changes: 50 additions & 0 deletions package.nls.ru.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"python.command.python.sortImports.title": "Отсортировать Imports",
"python.command.python.startREPL.title": "Открыть REPL",
"python.command.python.buildWorkspaceSymbols.title": "Собрать символы рабочего пространства",
"python.command.python.runtests.title": "Запустить все тесты",
"python.command.python.debugtests.title": "Запустить все тесты под отладчиком",
"python.command.python.execInTerminal.title": "Выполнить файл в консоли",
"python.command.python.setInterpreter.title": "Выбрать интерпретатор",
"python.command.python.updateSparkLibrary.title": "Обновить библиотеки PySpark",
"python.command.python.refactorExtractVariable.title": "Извлечь в переменную",
"python.command.python.refactorExtractMethod.title": "Извлечь в метод",
"python.command.python.viewTestOutput.title": "Показать вывод теста",
"python.command.python.selectAndRunTestMethod.title": "Запусть тестовый метод...",
"python.command.python.selectAndDebugTestMethod.title": "Отладить тестовый метод...",
"python.command.python.selectAndRunTestFile.title": "Запустить тестовый файл...",
"python.command.python.runCurrentTestFile.title": "Запустить текущий тестовый файл",
"python.command.python.runFailedTests.title": "Запустить непрошедшие тесты",
"python.command.python.execSelectionInTerminal.title": "Выполнить выбранный текст или текущую строку в консоли",
"python.command.python.execSelectionInDjangoShell.title": "Выполнить выбранный текст или текущую строку в оболочке Django",
"python.command.jupyter.runSelectionLine.title": "Выполнить выбранный текст или текущую строку",
"python.command.jupyter.execCurrentCell.title": "Выполнить ячейку",
"python.command.jupyter.execCurrentCellAndAdvance.title": "Выполнить ячейку и перейти к следующей",
"python.command.jupyter.gotToPreviousCell.title": "Перейти к предыдущей ячейке",
"python.command.jupyter.gotToNextCell.title": "Перейти к следующей ячейке",
"python.command.python.goToPythonObject.title": "Перейти к объекту Python",
"python.snippet.launch.standard.label": "Python",
"python.snippet.launch.standard.description": "Отладить программу Python со стандартным выводом",
"python.snippet.launch.pyspark.label": "Python: PySpark",
"python.snippet.launch.pyspark.description": "Отладка PySpark",
"python.snippet.launch.module.label": "Python: Модуль",
"python.snippet.launch.module.description": "Отладка модуля",
"python.snippet.launch.terminal.label": "Python: Интегрированная консоль",
"python.snippet.launch.terminal.description": "Отладка программы Python в интегрированной консоли",
"python.snippet.launch.externalTerminal.label": "Python: Внешний терминал",
"python.snippet.launch.externalTerminal.description": "Отладка программы Python во внешней консоли",
"python.snippet.launch.django.label": "Python: Django",
"python.snippet.launch.django.description": "Отладка приложения Django",
"python.snippet.launch.flask.label": "Python: Flask (0.11.x или новее)",
"python.snippet.launch.flask.description": "Отладка приложения Flask",
"python.snippet.launch.flaskOld.label": "Python: Flask (0.10.x или старее)",
"python.snippet.launch.flaskOld.description": "Отладка приложения Flask (старый стиль)",
"python.snippet.launch.pyramid.label": "Python: Приложение Pyramid",
"python.snippet.launch.pyramid.description": "Отладка приложения Pyramid",
"python.snippet.launch.watson.label": "Python: Приложение Watson",
"python.snippet.launch.watson.description": "Отладка приложения Watson",
"python.snippet.launch.attach.label": "Python: Подключить отладчик",
"python.snippet.launch.attach.description": "Подключить отладчик для удаленной отладки",
"python.snippet.launch.scrapy.label": "Python: Scrapy",
"python.snippet.launch.scrapy.description": "Scrapy в интегрированной консоли"
}
12 changes: 9 additions & 3 deletions src/client/providers/signatureProvider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

import { EOL } from 'os';
import * as vscode from 'vscode';
import { CancellationToken, Position, SignatureHelp, TextDocument } from 'vscode';
import { JediFactory } from '../languageServices/jediProxyFactory';
Expand Down Expand Up @@ -55,8 +56,13 @@ export class PythonSignatureProvider implements vscode.SignatureHelpProvider {
signature.activeParameter = def.paramindex;
// Don't display the documentation, as vs code doesn't format the docmentation.
// i.e. line feeds are not respected, long content is stripped.
const docLines = def.docstring.splitLines();
const label = docLines.shift().trim();
const documentation = docLines.join(EOL).trim();

const sig = <vscode.SignatureInformation>{
label: def.description,
label,
documentation,
parameters: []
};
sig.parameters = def.params.map(arg => {
Expand All @@ -65,7 +71,7 @@ export class PythonSignatureProvider implements vscode.SignatureHelpProvider {
}
return <vscode.ParameterInformation>{
documentation: arg.docstring.length > 0 ? arg.docstring : arg.description,
label: arg.description.length > 0 ? arg.description : arg.name
label: arg.name.trim()
};
});
signature.signatures.push(sig);
Expand All @@ -85,7 +91,7 @@ export class PythonSignatureProvider implements vscode.SignatureHelpProvider {
source: document.getText()
};
return this.jediFactory.getJediProxyHandler<proxy.IArgumentsResult>(document.uri).sendCommand(cmd, token).then(data => {
return PythonSignatureProvider.parseData(data);
return data ? PythonSignatureProvider.parseData(data) : new SignatureHelp();
});
}
}
6 changes: 6 additions & 0 deletions src/test/pythonFiles/signature/one.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Person:
def __init__(self, name, age = 23):
self.name = name
self.age = age

p1 = Person('Bob', )
1 change: 1 addition & 0 deletions src/test/pythonFiles/signature/two.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pow(c, 1,
90 changes: 90 additions & 0 deletions src/test/signature/signature.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';

import * as assert from 'assert';
import * as path from 'path';
import * as vscode from 'vscode';
import { closeActiveWindows, initialize, initializeTest } from '../initialize';

const autoCompPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'signature');
const fileOne = path.join(autoCompPath, 'one.py');
const fileTwo = path.join(autoCompPath, 'two.py');

class SignatureHelpResult {
constructor(
public line: number,
public index: number,
public signaturesCount: number,
public activeParameter: number,
public parameterName: string | null) { }
}

// tslint:disable-next-line:max-func-body-length
suite('Signatures', () => {
suiteSetup(async () => {
await initialize();
});
setup(initializeTest);
suiteTeardown(closeActiveWindows);
teardown(closeActiveWindows);

test('For ctor', async () => {
const expected = [
new SignatureHelpResult(5, 11, 0, 0, null),
new SignatureHelpResult(5, 12, 1, 0, 'name'),
new SignatureHelpResult(5, 13, 1, 0, 'name'),
new SignatureHelpResult(5, 14, 1, 0, 'name'),
new SignatureHelpResult(5, 15, 1, 0, 'name'),
new SignatureHelpResult(5, 16, 1, 0, 'name'),
new SignatureHelpResult(5, 17, 1, 0, 'name'),
new SignatureHelpResult(5, 18, 1, 1, 'age'),
new SignatureHelpResult(5, 19, 1, 1, 'age'),
new SignatureHelpResult(5, 20, 0, 0, null)
];

const document = await openDocument(fileOne);
for (const e of expected) {
await checkSignature(e, document!.uri);
}
});

test('For intrinsic', async () => {
const expected = [
new SignatureHelpResult(0, 0, 0, 0, null),
new SignatureHelpResult(0, 1, 0, 0, null),
new SignatureHelpResult(0, 2, 0, 0, null),
new SignatureHelpResult(0, 3, 0, 0, null),
new SignatureHelpResult(0, 4, 1, 0, 'x'),
new SignatureHelpResult(0, 5, 1, 0, 'x'),
new SignatureHelpResult(0, 6, 1, 1, 'y'),
new SignatureHelpResult(0, 7, 1, 1, 'y'),
new SignatureHelpResult(0, 8, 1, 1, 'y'),
new SignatureHelpResult(0, 9, 1, 2, 'z'),
new SignatureHelpResult(0, 10, 1, 2, 'z'),
new SignatureHelpResult(1, 0, 1, 2, 'z')
];

const document = await openDocument(fileTwo);
for (const e of expected) {
await checkSignature(e, document!.uri);
}
});
});

async function openDocument(documentPath: string): Promise<vscode.TextDocument | undefined> {
const document = await vscode.workspace.openTextDocument(documentPath);
await vscode.window.showTextDocument(document!);
return document;
}

async function checkSignature(expected: SignatureHelpResult, uri: vscode.Uri) {
const position = new vscode.Position(expected.line, expected.index);
const actual = await vscode.commands.executeCommand<vscode.SignatureHelp>('vscode.executeSignatureHelpProvider', uri, position);
assert.equal(actual!.signatures.length, expected.signaturesCount);
if (expected.signaturesCount > 0) {
assert.equal(actual!.activeParameter, expected.activeParameter);
const parameter = actual!.signatures[0].parameters[expected.activeParameter];
assert.equal(parameter.label, expected.parameterName);
}
}