diff --git a/apps/remix-ide/src/app/tabs/locales/en/editor.json b/apps/remix-ide/src/app/tabs/locales/en/editor.json index 33643eb0bb..b9c8c33568 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/editor.json +++ b/apps/remix-ide/src/app/tabs/locales/en/editor.json @@ -21,7 +21,7 @@ "editor.formatCode": "Format Code", "editor.generateDocumentation": "Generate documentation for this function", "editor.generateDocumentation2": "Generate documentation for the function \"{name}\"", - "editor.generateDocumentationByAI": "solidity code: {content}\n Generate the documentation for the function {currentFunction} using the Doxygen style syntax", + "editor.generateDocumentationByAI": "solidity code: {content}\n Generate the natspec documentation for the function {currentFunction} using the Doxygen style syntax", "editor.explainFunction": "Explain this function", "editor.explainFunctionSol": "Explain this code", "editor.explainFunction2": "Explain the function \"{name}\"", diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index 6f5518826b..32d6f5d6d1 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -16,6 +16,7 @@ import { retrieveNodesAtPosition } from './helpers/retrieveNodesAtPosition' import { RemixHoverProvider } from './providers/hoverProvider' import { RemixReferenceProvider } from './providers/referenceProvider' import { RemixCompletionProvider } from './providers/completionProvider' +import { RemixSolidityDocumentationProvider } from './providers/documentationProvider' import { RemixHighLightProvider } from './providers/highlightProvider' import { RemixDefinitionProvider } from './providers/definitionProvider' import { RemixCodeActionProvider } from './providers/codeActionProvider' @@ -23,6 +24,7 @@ import './remix-ui-editor.css' import { circomLanguageConfig, circomTokensProvider } from './syntaxes/circom' import { IPosition } from 'monaco-editor' import { RemixInLineCompletionProvider } from './providers/inlineCompletionProvider' +import { providers } from 'ethers' const _paq = (window._paq = window._paq || []) enum MarkerSeverity { @@ -174,6 +176,8 @@ export const EditorUI = (props: EditorUIProps) => { const currentFunction = useRef('') const currentFileRef = useRef('') const currentUrlRef = useRef('') + let currenFunctionNode = useRef('') + // const currentDecorations = useRef({ sourceAnnotationsPerFile: {}, markerPerFile: {} }) // decorations that are currently in use by the editor // const registeredDecorations = useRef({}) // registered decorations @@ -713,6 +717,12 @@ export const EditorUI = (props: EditorUIProps) => { } let gptGenerateDocumentationAction + const extractNatspecComments = (codeString: string): string => { + const natspecCommentRegex = /\/\*\*[\s\S]*?\*\//g; + const comments = codeString.match(natspecCommentRegex); + return comments ? comments[0] : ""; + } + const executeGptGenerateDocumentationAction = { id: 'generateDocumentation', label: intl.formatMessage({ id: 'editor.generateDocumentation' }), @@ -726,7 +736,23 @@ export const EditorUI = (props: EditorUIProps) => { const file = await props.plugin.call('fileManager', 'getCurrentFile') const content = await props.plugin.call('fileManager', 'readFile', file) const message = intl.formatMessage({ id: 'editor.generateDocumentationByAI' }, { content, currentFunction: currentFunction.current }) - await props.plugin.call('solcoder', 'code_explaining', message) + const cm = await props.plugin.call('solcoder', 'code_explaining', message) + + const natspecCom = extractNatspecComments(cm) + const cln = await props.plugin.call('codeParser', "getLineColumnOfNode", currenFunctionNode) + const range = new monacoRef.current.Range(cln.start.line, cln.start.column, cln.start.line, cln.start.column) + + // TODO: activate the provider to let the user accept the documentation suggestion + // const provider = new RemixSolidityDocumentationProvider(natspecCom) + // editor.inlineProviderDisposable = monacoRef.current.languages.registerInlineCompletionsProvider('remix-docu', provider) + + editor.executeEdits('inlineCompletionDocu', [ + { + range: range, + text: natspecCom, + forceMoveMarkers: true, + }, + ]); _paq.push(['trackEvent', 'ai', 'solcoder', 'generateDocumentation']) }, } @@ -845,6 +871,8 @@ export const EditorUI = (props: EditorUIProps) => { const functionImpl = nodesAtPosition.find((node) => node.kind === 'function') if (functionImpl) { currentFunction.current = functionImpl.name + currenFunctionNode = functionImpl + executeGptGenerateDocumentationAction.label = intl.formatMessage({ id: 'editor.generateDocumentation2' }, { name: functionImpl.name }) gptGenerateDocumentationAction = editor.addAction(executeGptGenerateDocumentationAction) executegptExplainFunctionAction.label = intl.formatMessage({ id: 'editor.explainFunction2' }, { name: functionImpl.name })