Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 43 additions & 0 deletions localtypings/pxteditor.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// <reference path="../built/pxtlib.d.ts" />
/// <reference path="./projectheader.d.ts" />
/// <reference path="./validatorPlan.d.ts" />
/// <reference path="./monaco.d.ts" />

declare namespace pxt.editor {
export interface EditorMessage {
Expand Down Expand Up @@ -1155,6 +1156,7 @@ declare namespace pxt.editor {
onCodeStop?: () => void;

experiments?: Experiment[];
monacoFieldEditors?: MonacoFieldEditorDefinition[];
}

export interface Experiment {
Expand Down Expand Up @@ -1368,6 +1370,47 @@ declare namespace pxt.editor {
}

type AssetEditorEvent = AssetEditorRequestSaveEvent | AssetEditorReadyEvent;

export interface TextEdit {
range: monaco.Range;
replacement: string;
}

export interface MonacoFieldEditorHost {
contentDiv(): HTMLDivElement;
getText(range: monaco.Range): string;
blocksInfo(): pxtc.BlocksInfo;

package(): pxt.MainPackage;
writeFileAsync(filename: string, content: string): Promise<void>;
readFile(filename: string): string;
}

export interface MonacoFieldEditor {
getId(): string;
showEditorAsync(fileType: pxt.editor.FileType, editrange: monaco.Range, host: MonacoFieldEditorHost): Promise<TextEdit>;
onClosed(): void;
dispose(): void;
}

export interface MonacoFieldEditorDefinition {
id: string;
matcher: MonacoFindArguments;
foldMatches?: boolean;
alwaysBuildOnClose?: boolean;
glyphCssClass?: string;
weight?: number; // higher weight will override lower weight when on same line
proto: { new(): MonacoFieldEditor };
heightInPixels?: number;
}

export interface MonacoFindArguments {
searchString: string;
isRegex: boolean;
matchWholeWord: boolean;
matchCase: boolean;
validateRange?: (range: monaco.Range, model: monaco.editor.ITextModel) => monaco.Range;
}
}

declare namespace pxt.workspace {
Expand Down
4 changes: 2 additions & 2 deletions pxteditor/monaco-fields/field_musiceditor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MonacoReactFieldEditor } from "./field_react";
import { MonacoFieldEditorDefinition, registerMonacoFieldEditor } from "./monacoFieldEditor";
import { registerMonacoFieldEditor } from "./monacoFieldEditor";

const fieldEditorId = "music-editor";

Expand Down Expand Up @@ -91,7 +91,7 @@ function createFakeAsset(song: pxt.assets.music.Song): pxt.Song {
}
}

export const songEditorDefinition: MonacoFieldEditorDefinition = {
export const songEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = {
id: fieldEditorId,
foldMatches: true,
glyphCssClass: "fas fa-music sprite-focus-hover",
Expand Down
10 changes: 4 additions & 6 deletions pxteditor/monaco-fields/field_react.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { MonacoFieldEditor, TextEdit, MonacoFieldEditorHost } from "./monacoFieldEditor";

const fieldEditorId = "image-editor";

export class MonacoReactFieldEditor<U> implements MonacoFieldEditor {
private resolver: (edit: TextEdit) => void;
export class MonacoReactFieldEditor<U> implements pxt.editor.MonacoFieldEditor {
private resolver: (edit: pxt.editor.TextEdit) => void;
private rejecter: (err?: any) => void;

protected fileType: pxt.editor.FileType;
protected editrange: monaco.Range;
protected host: MonacoFieldEditorHost;
protected host: pxt.editor.MonacoFieldEditorHost;
protected fv: pxt.react.FieldEditorView<U>;

getId() {
return fieldEditorId;
}

showEditorAsync(fileType: pxt.editor.FileType, editrange: monaco.Range, host: MonacoFieldEditorHost): Promise<TextEdit> {
showEditorAsync(fileType: pxt.editor.FileType, editrange: monaco.Range, host: pxt.editor.MonacoFieldEditorHost): Promise<pxt.editor.TextEdit> {
this.fileType = fileType;
this.editrange = editrange;
this.host = host;
Expand Down
4 changes: 2 additions & 2 deletions pxteditor/monaco-fields/field_soundEffect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MonacoReactFieldEditor } from "./field_react";
import { MonacoFieldEditorDefinition, registerMonacoFieldEditor } from "./monacoFieldEditor";
import { registerMonacoFieldEditor } from "./monacoFieldEditor";

const fieldEditorId = "soundeffect-editor";

Expand Down Expand Up @@ -205,7 +205,7 @@ function defaultSound(): pxt.assets.Sound {
}
}

export const soundEditorDefinition: MonacoFieldEditorDefinition = {
export const soundEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = {
id: fieldEditorId,
foldMatches: true,
glyphCssClass: "fas fa-music sprite-focus-hover",
Expand Down
4 changes: 2 additions & 2 deletions pxteditor/monaco-fields/field_sprite.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MonacoReactFieldEditor } from "./field_react";
import { MonacoFieldEditorDefinition, registerMonacoFieldEditor } from "./monacoFieldEditor";
import { registerMonacoFieldEditor } from "./monacoFieldEditor";

const fieldEditorId = "image-editor";

Expand Down Expand Up @@ -76,7 +76,7 @@ function createFakeAsset(bitmap: pxt.sprite.Bitmap): pxt.ProjectImage {
}
}

export const spriteEditorDefinition: MonacoFieldEditorDefinition = {
export const spriteEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = {
id: fieldEditorId,
foldMatches: true,
glyphCssClass: "sprite-editor-glyph sprite-focus-hover",
Expand Down
4 changes: 2 additions & 2 deletions pxteditor/monaco-fields/field_tilemap.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MonacoReactFieldEditor } from "./field_react";
import { MonacoFieldEditorDefinition, registerMonacoFieldEditor } from "./monacoFieldEditor";
import { registerMonacoFieldEditor } from "./monacoFieldEditor";

const fieldEditorId = "tilemap-editor";

Expand Down Expand Up @@ -139,7 +139,7 @@ function createFakeAsset(data: pxt.sprite.TilemapData): pxt.ProjectTilemap {
}
}

export const tilemapEditorDefinition: MonacoFieldEditorDefinition = {
export const tilemapEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = {
id: fieldEditorId,
foldMatches: true,
alwaysBuildOnClose: true,
Expand Down
44 changes: 2 additions & 42 deletions pxteditor/monaco-fields/monacoFieldEditor.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,9 @@
/// <reference path="../../localtypings/monaco.d.ts" />

export interface TextEdit {
range: monaco.Range;
replacement: string;
}

export interface MonacoFieldEditorHost {
contentDiv(): HTMLDivElement;
getText(range: monaco.Range): string;
blocksInfo(): pxtc.BlocksInfo;

package(): pxt.MainPackage;
writeFileAsync(filename: string, content: string): Promise<void>;
readFile(filename: string): string;
}

export interface MonacoFieldEditor {
getId(): string;
showEditorAsync(fileType: pxt.editor.FileType, editrange: monaco.Range, host: MonacoFieldEditorHost): Promise<TextEdit>;
onClosed(): void;
dispose(): void;
}

export interface MonacoFieldEditorDefinition {
id: string;
matcher: MonacoFindArguments;
foldMatches?: boolean;
alwaysBuildOnClose?: boolean;
glyphCssClass?: string;
weight?: number; // higher weight will override lower weight when on same line
proto: { new(): MonacoFieldEditor };
heightInPixels?: number;
}

export interface MonacoFindArguments {
searchString: string;
isRegex: boolean;
matchWholeWord: boolean;
matchCase: boolean;
validateRange?: (range: monaco.Range, model: monaco.editor.ITextModel) => monaco.Range;
}

const definitions: pxt.Map<MonacoFieldEditorDefinition> = {};
const definitions: pxt.Map<pxt.editor.MonacoFieldEditorDefinition> = {};

export function registerMonacoFieldEditor(name: string, definition: MonacoFieldEditorDefinition) {
export function registerMonacoFieldEditor(name: string, definition: pxt.editor.MonacoFieldEditorDefinition) {
definitions[name] = definition;
}

Expand Down
6 changes: 6 additions & 0 deletions webapp/src/cmds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as pxtblockly from "../../pxtblocks";
import ExtensionResult = pxt.editor.ExtensionResult;
import NativeHostMessage = pxt.editor.NativeHostMessage;
import { setEditorExtensionExperiments } from "../../pxteditor/experiments";
import { registerMonacoFieldEditor } from "../../pxteditor";


function log(msg: string) {
Expand Down Expand Up @@ -401,6 +402,11 @@ function applyExtensionResult() {
if (res.experiments) {
setEditorExtensionExperiments(res.experiments);
}
if (res.monacoFieldEditors) {
for (const def of res.monacoFieldEditors) {
registerMonacoFieldEditor(def.id, def);
}
}
}

export async function initAsync() {
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/monaco.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1606,7 +1606,7 @@ export class Editor extends toolboxeditor.ToolboxEditor {
}
}

showFieldEditor(range: monaco.Range, fe: pxteditor.MonacoFieldEditor, viewZoneHeight: number, buildAfter: boolean) {
showFieldEditor(range: monaco.Range, fe: pxt.editor.MonacoFieldEditor, viewZoneHeight: number, buildAfter: boolean) {
if (this.feWidget) {
this.feWidget.close();
}
Expand Down
17 changes: 8 additions & 9 deletions webapp/src/monacoFieldEditorHost.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/// <reference path="../../localtypings/monaco.d.ts" />

import { MonacoFieldEditor, MonacoFieldEditorDefinition, MonacoFieldEditorHost, TextEdit } from "../../pxteditor";
import * as compiler from "./compiler";
import * as pkg from "./package";

Expand All @@ -11,7 +10,7 @@ interface OwnedRange {
id: number;
}

export class ViewZoneEditorHost implements MonacoFieldEditorHost, monaco.editor.IViewZone {
export class ViewZoneEditorHost implements pxt.editor.MonacoFieldEditorHost, monaco.editor.IViewZone {
domNode: HTMLDivElement;
afterLineNumber: number;
heightInPx = 520;
Expand All @@ -26,7 +25,7 @@ export class ViewZoneEditorHost implements MonacoFieldEditorHost, monaco.editor.

suppressMouseDown = false;

constructor(protected fe: MonacoFieldEditor, protected range: monaco.Range, protected model: monaco.editor.IModel) {
constructor(protected fe: pxt.editor.MonacoFieldEditor, protected range: monaco.Range, protected model: monaco.editor.IModel) {
this.afterLineNumber = range.endLineNumber;

const outer = document.createElement("div");
Expand All @@ -52,7 +51,7 @@ export class ViewZoneEditorHost implements MonacoFieldEditorHost, monaco.editor.
return this.content;
}

showAsync(fileType: pxt.editor.FileType, editor: monaco.editor.IStandaloneCodeEditor): Promise<TextEdit> {
showAsync(fileType: pxt.editor.FileType, editor: monaco.editor.IStandaloneCodeEditor): Promise<pxt.editor.TextEdit> {
this.fileType = fileType;
this.editor = editor;
return compiler.getBlocksAsync()
Expand Down Expand Up @@ -132,10 +131,10 @@ export class ViewZoneEditorHost implements MonacoFieldEditorHost, monaco.editor.
}
}

export class ModalEditorHost implements MonacoFieldEditorHost {
export class ModalEditorHost implements pxt.editor.MonacoFieldEditorHost {
protected blocks: pxtc.BlocksInfo;

constructor(protected fe: MonacoFieldEditor, protected range: monaco.Range, protected model: monaco.editor.IModel) {
constructor(protected fe: pxt.editor.MonacoFieldEditor, protected range: monaco.Range, protected model: monaco.editor.IModel) {
}

contentDiv(): HTMLDivElement {
Expand Down Expand Up @@ -164,7 +163,7 @@ export class ModalEditorHost implements MonacoFieldEditorHost {
return this.package().host().readFile(pkg.mainPkg, filename);
}

showAsync(fileType: pxt.editor.FileType, editor: monaco.editor.IStandaloneCodeEditor): Promise<TextEdit> {
showAsync(fileType: pxt.editor.FileType, editor: monaco.editor.IStandaloneCodeEditor): Promise<pxt.editor.TextEdit> {
return compiler.getBlocksAsync()
.then(bi => {
this.blocks = bi;
Expand All @@ -179,7 +178,7 @@ export class ModalEditorHost implements MonacoFieldEditorHost {
}

export class FieldEditorManager implements monaco.languages.FoldingRangeProvider {
protected fieldEditors: MonacoFieldEditorDefinition[] = [];
protected fieldEditors: pxt.editor.MonacoFieldEditorDefinition[] = [];
protected decorations: pxt.Map<string[]> = {};
protected liveRanges: OwnedRange[] = [];
protected fieldEditorsEnabled = true;
Expand Down Expand Up @@ -213,7 +212,7 @@ export class FieldEditorManager implements monaco.languages.FoldingRangeProvider
}
}

addFieldEditor(definition: MonacoFieldEditorDefinition) {
addFieldEditor(definition: pxt.editor.MonacoFieldEditorDefinition) {
for (const f of this.fieldEditors) {
if (f.id === definition.id) return;
}
Expand Down