|
|
|
@ -152,6 +152,7 @@ export const EditorUI = (props: EditorUIProps) => { |
|
|
|
|
const pasteCodeRef = useRef(false) |
|
|
|
|
const editorRef = useRef(null) |
|
|
|
|
const monacoRef = useRef<Monaco>(null) |
|
|
|
|
const currentFunction = useRef('') |
|
|
|
|
const currentFileRef = useRef('') |
|
|
|
|
const currentUrlRef = useRef('') |
|
|
|
|
// const currentDecorations = useRef({ sourceAnnotationsPerFile: {}, markerPerFile: {} }) // decorations that are currently in use by the editor
|
|
|
|
@ -683,7 +684,43 @@ export const EditorUI = (props: EditorUIProps) => { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const freeFunctionCondition = editor.createContextKey('freeFunctionCondition', false) |
|
|
|
|
let gptGenerateDocumentationAction |
|
|
|
|
const executeGptGenerateDocumentationAction = { |
|
|
|
|
id: "generateDocumentation", |
|
|
|
|
label: "Generate documentation for this function", |
|
|
|
|
contextMenuOrder: 0, // choose the order
|
|
|
|
|
contextMenuGroupId: "gtp", // create a new grouping
|
|
|
|
|
keybindings: [], |
|
|
|
|
run: async () => { |
|
|
|
|
const file = await props.plugin.call('fileManager', 'getCurrentFile') |
|
|
|
|
const content = await props.plugin.call('fileManager', 'readFile', file) |
|
|
|
|
const message = ` |
|
|
|
|
solidity code: ${content} |
|
|
|
|
Generate the documentation for the function ${currentFunction.current} using the Doxygen style syntax |
|
|
|
|
` |
|
|
|
|
await props.plugin.call('openaigpt', 'message', message) |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let gptExplainFunctionAction |
|
|
|
|
const executegptExplainFunctionAction = { |
|
|
|
|
id: "generateDocumentation", |
|
|
|
|
label: "Explain this function", |
|
|
|
|
contextMenuOrder: 0, // choose the order
|
|
|
|
|
contextMenuGroupId: "gtp", // create a new grouping
|
|
|
|
|
keybindings: [], |
|
|
|
|
run: async () => { |
|
|
|
|
const file = await props.plugin.call('fileManager', 'getCurrentFile') |
|
|
|
|
const content = await props.plugin.call('fileManager', 'readFile', file) |
|
|
|
|
const message = ` |
|
|
|
|
solidity code: ${content} |
|
|
|
|
Explain the function ${currentFunction.current} |
|
|
|
|
` |
|
|
|
|
await props.plugin.call('openaigpt', 'message', message) |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const freeFunctionCondition = editor.createContextKey('freeFunctionCondition', false); |
|
|
|
|
let freeFunctionAction |
|
|
|
|
const executeFreeFunctionAction = { |
|
|
|
|
id: 'executeFreeFunction', |
|
|
|
@ -715,6 +752,8 @@ export const EditorUI = (props: EditorUIProps) => { |
|
|
|
|
editor.addAction(zoomOutAction) |
|
|
|
|
editor.addAction(zoominAction) |
|
|
|
|
freeFunctionAction = editor.addAction(executeFreeFunctionAction) |
|
|
|
|
gptGenerateDocumentationAction = editor.addAction(executeGptGenerateDocumentationAction) |
|
|
|
|
gptExplainFunctionAction = editor.addAction(executegptExplainFunctionAction) |
|
|
|
|
|
|
|
|
|
// we have to add the command because the menu action isn't always available (see onContextMenuHandlerForFreeFunction)
|
|
|
|
|
editor.addCommand(monacoRef.current.KeyMod.Shift | monacoRef.current.KeyMod.Alt | monacoRef.current.KeyCode.KeyR, () => executeFreeFunctionAction.run()) |
|
|
|
@ -726,6 +765,15 @@ export const EditorUI = (props: EditorUIProps) => { |
|
|
|
|
freeFunctionAction.dispose() |
|
|
|
|
freeFunctionAction = null |
|
|
|
|
} |
|
|
|
|
if (gptGenerateDocumentationAction) { |
|
|
|
|
gptGenerateDocumentationAction.dispose() |
|
|
|
|
gptGenerateDocumentationAction = null |
|
|
|
|
} |
|
|
|
|
if (gptExplainFunctionAction) { |
|
|
|
|
gptExplainFunctionAction.dispose() |
|
|
|
|
gptExplainFunctionAction = null |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const file = await props.plugin.call('fileManager', 'getCurrentFile') |
|
|
|
|
if (!file.endsWith('.sol')) { |
|
|
|
|
freeFunctionCondition.set(false) |
|
|
|
@ -737,6 +785,14 @@ export const EditorUI = (props: EditorUIProps) => { |
|
|
|
|
executeFreeFunctionAction.label = `Run the free function "${freeFunctionNode.name}" in the Remix VM` |
|
|
|
|
freeFunctionAction = editor.addAction(executeFreeFunctionAction) |
|
|
|
|
} |
|
|
|
|
const functionImpl = nodesAtPosition.find((node) => node.kind === 'function')
|
|
|
|
|
if (functionImpl) { |
|
|
|
|
currentFunction.current = functionImpl.name |
|
|
|
|
executeGptGenerateDocumentationAction.label = `Generate documentation for the function "${functionImpl.name}"` |
|
|
|
|
gptGenerateDocumentationAction = editor.addAction(executeGptGenerateDocumentationAction) |
|
|
|
|
executegptExplainFunctionAction.label = `Explain the function "${functionImpl.name}"` |
|
|
|
|
gptExplainFunctionAction = editor.addAction(executegptExplainFunctionAction) |
|
|
|
|
} |
|
|
|
|
freeFunctionCondition.set(!!freeFunctionNode) |
|
|
|
|
} |
|
|
|
|
contextmenu._onContextMenu = (...args) => { |
|
|
|
|