Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
59ec99c
init
cosmicshuai Mar 31, 2021
bf729cb
Merge branch 'main' into shuwan/LuGotoDefinition
cosmicshuai Apr 1, 2021
78c4395
add import regex rules
cosmicshuai Apr 1, 2021
012aedb
add navigation
Apr 1, 2021
5a1ccae
Merge branch 'main' into shuwan/LuGotoDefinition
cosmicshuai Apr 2, 2021
f736a80
add a check file existence before navigation
cosmicshuai Apr 2, 2021
000719e
Merge branch 'main' into shuwan/LuGotoDefinition
Apr 6, 2021
b2df00a
Merge branch 'main' into shuwan/LuGotoDefinition
Apr 6, 2021
5dc19f3
simplify code
cosmicshuai Apr 6, 2021
10b97be
Merge branch 'shuwan/LuGotoDefinition' of https://github.com/microsof…
cosmicshuai Apr 6, 2021
bfcbb0d
fix lint issue
cosmicshuai Apr 6, 2021
d306526
Merge branch 'main' into shuwan/LuGotoDefinition
Apr 7, 2021
bbb72b0
Merge branch 'main' into shuwan/LuGotoDefinition
hatpick Apr 7, 2021
45e261c
Merge branch 'main' into shuwan/LuGotoDefinition
Apr 8, 2021
5d0199f
Merge branch 'main' into shuwan/LuGotoDefinition
Apr 8, 2021
00ea91a
Merge branch 'main' into shuwan/LuGotoDefinition
Apr 9, 2021
8b70475
re-enable context menu in lu editor
cosmicshuai Apr 9, 2021
a83bbad
Merge branch 'shuwan/LuGotoDefinition' of https://github.com/microsof…
cosmicshuai Apr 9, 2021
c98130a
Merge branch 'main' into shuwan/LuGotoDefinition
Apr 9, 2021
256e8ca
Merge branch 'main' into shuwan/LuGotoDefinition
hatpick Apr 9, 2021
fd2be03
Merge branch 'main' into shuwan/LuGotoDefinition
hatpick Apr 9, 2021
3849b01
Merge branch 'main' into shuwan/LuGotoDefinition
hatpick Apr 9, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import { CodeEditorSettings } from '@bfc/shared';
import { useRecoilValue } from 'recoil';
import { LuFile } from '@bfc/shared';

import { localeState, settingsState } from '../../recoilModel/atoms';
import { dialogState, localeState, settingsState } from '../../recoilModel/atoms';
import { userSettingsState, dispatcherState, luFilesSelectorFamily } from '../../recoilModel';
import { navigateTo } from '../../utils/navigation';
import TelemetryClient from '../../telemetry/TelemetryClient';

import { DiffCodeEditor } from './diff-editor';
Expand Down Expand Up @@ -43,6 +44,7 @@ const CodeEditor: React.FC<CodeEditorProps> = (props) => {
const luFiles = useRecoilValue(luFilesSelectorFamily(actualProjectId));
const locale = useRecoilValue(localeState(actualProjectId));
const settings = useRecoilValue(settingsState(actualProjectId));
const currentDialog = useRecoilValue(dialogState({ projectId: actualProjectId, dialogId }));

const { languages, defaultLanguage } = settings;

Expand Down Expand Up @@ -145,6 +147,19 @@ const CodeEditor: React.FC<CodeEditorProps> = (props) => {
updateUserSettings({ codeEditor: settings });
};

const navigateToLuPage = useCallback(
(luFileId: string, sectionId?: string) => {
// eslint-disable-next-line security/detect-non-literal-regexp
const pattern = new RegExp(`.${locale}`, 'g');
const fileId = currentDialog.isFormDialog ? luFileId : luFileId.replace(pattern, '');
const url = currentDialog.isFormDialog
? `/bot/${projectId}/language-understanding/${currentDialog.id}/item/${fileId}`
: `/bot/${projectId}/language-understanding/${fileId}${sectionId ? `/edit?t=${sectionId}` : ''}`;
navigateTo(url);
},
[projectId, locale, currentDialog]
);

const currentLanguageFileEditor = useMemo(() => {
return (
<LuEditor
Expand All @@ -160,6 +175,7 @@ const CodeEditor: React.FC<CodeEditorProps> = (props) => {
value={content}
onChange={onChange}
onChangeSettings={handleSettingsChange}
onNavigateToLuPage={navigateToLuPage}
/>
);
}, [luOption, file]);
Expand Down
27 changes: 24 additions & 3 deletions Composer/packages/lib/code-editor/src/LuEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,11 @@ const LuEditor: React.FC<LULSPEditorProps> = (props) => {
autoClosingBrackets: 'always' as const,
autoIndent: 'full' as const,
folding: true,
definitions: true,
lightbulb: {
enabled: true,
},
contextmenu: false,
contextmenu: true,
...props.options,
};

Expand Down Expand Up @@ -153,7 +154,24 @@ const LuEditor: React.FC<LULSPEditorProps> = (props) => {
const [labelingMenuVisible, setLabelingMenuVisible] = useState(false);
const editorDomRef = useRef<HTMLElement | null>(null);

const onLuNavigationMsg = (
languageClient: MonacoLanguageClient,
onNavigateToLuPage: ((luFileId: string, luSectionId?: string | undefined) => void) | undefined
) => {
return languageClient.onReady().then(() =>
languageClient.onNotification('LuGotoDefinition', (result) => {
if (luOption?.projectId) {
onNavigateToLuPage?.(result.fileId, result.intent);
}
})
);
};

useEffect(() => {
if (props.options?.readOnly) {
return;
}

if (!editor) return;

if (!window.monacoServiceInstance) {
Expand All @@ -169,7 +187,7 @@ const LuEditor: React.FC<LULSPEditorProps> = (props) => {
webSocket,
onConnection: (connection: MessageConnection) => {
const languageClient = createLanguageClient(formatMessage('LU Language Client'), ['lu'], connection);

onLuNavigationMsg(languageClient, onNavigateToLuPage);
const m = monacoRef.current;
if (m) {
// this is the correct way to combine key codes in Monaco
Expand All @@ -190,6 +208,7 @@ const LuEditor: React.FC<LULSPEditorProps> = (props) => {
editor.executeEdits(uri, edits);
})
);

const disposable = languageClient.start();
connection.onClose(() => disposable.dispose());
window.monacoLUEditorInstance = languageClient;
Expand All @@ -198,6 +217,8 @@ const LuEditor: React.FC<LULSPEditorProps> = (props) => {
} else {
const m = monacoRef.current;
const languageClient = window.monacoLUEditorInstance;
onLuNavigationMsg(languageClient, onNavigateToLuPage);

if (m) {
// this is the correct way to combine keycodes in Monaco
// eslint-disable-next-line no-bitwise
Expand All @@ -208,7 +229,7 @@ const LuEditor: React.FC<LULSPEditorProps> = (props) => {
}
sendRequestWithRetry(languageClient, 'initializeDocuments', { luOption, uri });
}
}, [editor]);
}, [editor, onNavigateToLuPage]);

const onInit: OnInit = (monaco) => {
registerLULanguage(monaco);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import path from 'path';

import URI from 'vscode-uri';
import { FoldingRangeParams, IConnection, TextDocuments } from 'vscode-languageserver';
Expand Down Expand Up @@ -36,6 +37,8 @@ export class LUServer {
protected readonly pendingValidationRequests = new Map<string, number>();
protected LUDocuments: LUDocument[] = [];
private luParser = new LuParser();
private _curFileId = '';
private _curProjectId = '';

constructor(
protected readonly connection: IConnection,
Expand Down Expand Up @@ -66,6 +69,7 @@ export class LUServer {
capabilities: {
textDocumentSync: this.documents.syncKind,
codeActionProvider: false,
definitionProvider: true,
completionProvider: {
resolveProvider: true,
triggerCharacters: ['@', ' ', '{', ':', '[', '('],
Expand All @@ -79,6 +83,7 @@ export class LUServer {
});
this.connection.onCompletion((params) => this.completion(params));
this.connection.onDocumentOnTypeFormatting((docTypingParams) => this.docTypeFormat(docTypingParams));
this.connection.onDefinition((params: TextDocumentPositionParams) => this.definitionHandler(params));
this.connection.onFoldingRanges((foldingRangeParams: FoldingRangeParams) =>
this.foldingRangeHandler(foldingRangeParams)
);
Expand All @@ -101,6 +106,36 @@ export class LUServer {
this.connection.listen();
}

protected definitionHandler(params: TextDocumentPositionParams): undefined {
const document = this.documents.get(params.textDocument.uri);
if (!document) {
return;
}

const curLine = document.getText().split(/\r?\n/g)[params.position.line];
// eslint-disable-next-line security/detect-unsafe-regex
const importRegex = /^\s*-?\s*\[[^[\]]+\](\(([^()#]+)(#([a-zA-Z0-9_-]*))?(\*([a-zA-Z0-9_-]+)\*)?\))/;
if (importRegex.test(curLine)) {
const importedFile = curLine.match(importRegex);
if (importedFile) {
const target = importedFile[2];
const intent = importedFile[4];
const fileId = path.parse(target).name;
const targetFile = this.importResolver?.(this._curFileId, target, this._curProjectId);
if (targetFile) {
this.connection.sendNotification('LuGotoDefinition', {
fileId: fileId,
intent: intent,
});
}

return;
}
}

return;
}

protected async foldingRangeHandler(params: FoldingRangeParams): Promise<FoldingRange[]> {
const document = this.documents.get(params.textDocument.uri);
if (!document) {
Expand Down Expand Up @@ -191,6 +226,8 @@ export class LUServer {
}

const id = fileId || uri;
this._curFileId = id;
this._curProjectId = projectId || '';
const { intents: sections, diagnostics } = await this.luParser.parse(content, id, luFeatures);

return { sections, diagnostics, content };
Expand Down