From 4b0dc90e8d56fbf35dc8dd34f5be2494ad4f1479 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 8 Jul 2021 11:34:31 -0500 Subject: [PATCH] editor: improve template snippets - fix always being suggested - add more imports - reduce duplicated code Fixes https://github.com/pybricks/pybricks-code/issues/471 --- CHANGELOG.md | 6 ++ src/editor/Editor.tsx | 4 +- src/editor/pybricksMicroPython.ts | 132 +++++++++++++++++------------- 3 files changed, 83 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be4d3a28..83555f5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ # Changelog +## [Unreleased] + +### Changed +- Changed snippet (autocomplete) content and behavior [issue#471]. + ## [1.1.0-beta.2] - 2021-07-06 ## Changed @@ -33,6 +38,7 @@ Prerelease changes are documented at [support#48]. +[issue#471]: https://github.com/pybricks/pybricks-code/issues/471 [support#48]: https://github.com/pybricks/support/issues/48 [support#378]: https://github.com/pybricks/support/issues/378 [v3.0.0]: https://github.com/pybricks/pybricks-micropython/blob/master/CHANGELOG.md#300---2021-06-08 diff --git a/src/editor/Editor.tsx b/src/editor/Editor.tsx index 2a73f764..acb0794c 100644 --- a/src/editor/Editor.tsx +++ b/src/editor/Editor.tsx @@ -46,11 +46,9 @@ toDispose.push( pybricksMicroPythonId, pybricksMicroPython.language, ), -); -toDispose.push( monaco.languages.registerCompletionItemProvider( pybricksMicroPythonId, - pybricksMicroPython.completions, + pybricksMicroPython.templateSnippetCompletions, ), ); diff --git a/src/editor/pybricksMicroPython.ts b/src/editor/pybricksMicroPython.ts index 2865df04..83bce69b 100644 --- a/src/editor/pybricksMicroPython.ts +++ b/src/editor/pybricksMicroPython.ts @@ -236,67 +236,87 @@ export const language = { }, }; -export const completions = { - provideCompletionItems: (_model, position, _context, _token) => { - return { - suggestions: [ - { - label: 'technichub', - kind: monaco.languages.CompletionItemKind.Snippet, - insertText: `from pybricks.hubs import TechnicHub -from pybricks.pupdevices import Motor -from pybricks.parameters import Port, Stop, Color -from pybricks.tools import wait +function template(hubName: string, devices: string[]): string { + return `from pybricks.hubs import ${hubName} +from pybricks.pupdevices import ${devices.join(', ')} +from pybricks.parameters import Button, Color, Direction, Port, Stop +from pybricks.robotics import DriveBase +from pybricks.tools import wait, StopWatch -hub = TechnicHub()`, - range: monaco.Range.fromPositions(position), - }, - { - label: 'cityhub', - kind: monaco.languages.CompletionItemKind.Snippet, - insertText: `from pybricks.hubs import CityHub -from pybricks.pupdevices import Motor -from pybricks.parameters import Port, Stop, Color -from pybricks.tools import wait +hub = ${hubName}()`; +} -hub = CityHub()`, - range: monaco.Range.fromPositions(position), - }, - { - label: 'movehub', - kind: monaco.languages.CompletionItemKind.Snippet, - insertText: `from pybricks.hubs import MoveHub -from pybricks.pupdevices import Motor -from pybricks.parameters import Port, Stop, Color -from pybricks.tools import wait +const templateSnippets: Array< + Required< + Pick + > & { label: string } +> = [ + { + label: 'technichub', + documentation: 'Template for Technic hub program.', + insertText: template('TechnicHub', ['Motor']), + }, + { + label: 'cityhub', + documentation: 'Template for City hub program.', + insertText: template('CityHub', ['DCMotor', 'Light']), + }, + { + label: 'movehub', + documentation: 'Template for BOOST Move hub program.', + insertText: template('MoveHub', ['Motor', 'ColorDistanceSensor']), + }, + { + label: 'primehub', + documentation: 'Template for SPIKE Prime program.', + insertText: template('PrimeHub', [ + 'Motor', + 'ColorSensor', + 'UltrasonicSensor', + 'ForceSensor', + ]), + }, + { + label: 'inventorhub', + documentation: 'Template for MINDSTORMS Robot Inventor hub program.', + insertText: template('InventorHub', [ + 'Motor', + 'ColorSensor', + 'UltrasonicSensor', + ]), + }, +]; -hub = MoveHub()`, - range: monaco.Range.fromPositions(position), - }, - { - label: 'primehub', - kind: monaco.languages.CompletionItemKind.Snippet, - insertText: `from pybricks.hubs import PrimeHub -from pybricks.pupdevices import Motor, ColorSensor, ForceSensor, UltrasonicSensor -from pybricks.parameters import Port, Stop, Color, Button -from pybricks.tools import wait +export const templateSnippetCompletions = { + provideCompletionItems: (model, position, _context, _token) => { + // templates snippets are only available on the first line + if (position.lineNumber !== 1) { + return undefined; + } -hub = PrimeHub()`, - range: monaco.Range.fromPositions(position), - }, - { - label: 'inventorhub', - kind: monaco.languages.CompletionItemKind.Snippet, - insertText: `from pybricks.hubs import InventorHub -from pybricks.pupdevices import Motor, ColorSensor, UltrasonicSensor -from pybricks.parameters import Port, Stop, Color, Button -from pybricks.tools import wait - -hub = InventorHub()`, - range: monaco.Range.fromPositions(position), - }, - ], + const range = { + startLineNumber: position.lineNumber, + startColumn: 1, + endLineNumber: position.lineNumber, + endColumn: position.column, }; + + const textUntilPosition = model.getValueInRange(range); + + const items = templateSnippets + .filter((x) => x.label.startsWith(textUntilPosition)) + .map((x) => ({ + detail: x.insertText, + kind: monaco.languages.CompletionItemKind.Snippet, + range, + ...x, + })); + + if (!items) { + return undefined; + } + + return { suggestions: items }; }, };