diff --git a/extensions/void/.vscode/launch.json b/extensions/void/.vscode/launch.json index 88804653..17ab1d57 100644 --- a/extensions/void/.vscode/launch.json +++ b/extensions/void/.vscode/launch.json @@ -10,7 +10,8 @@ "type": "extensionHost", "request": "launch", "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" + "--extensionDevelopmentPath=${workspaceFolder}", + "--enable-proposed-api=void.void", ], "outFiles": [ "${workspaceFolder}/out/**/*.js" @@ -18,4 +19,4 @@ "preLaunchTask": "${defaultBuildTask}" } ] -} +} \ No newline at end of file diff --git a/extensions/void/build/build.js b/extensions/void/build/build.js index 8b2ab8be..d1be3bb0 100644 --- a/extensions/void/build/build.js +++ b/extensions/void/build/build.js @@ -49,6 +49,11 @@ const convertTSXtoJS = async ({ from, to }) => { to: 'dist/webviews/ctrlk/index.js', }) + await convertTSXtoJS({ + from: 'src/webviews/diffline/index.tsx', + to: 'dist/webviews/diffline/index.js', + }) + // convert tailwind to css await convertTailwindToCSS({ from: 'src/webviews/styles.css', diff --git a/extensions/void/package.json b/extensions/void/package.json index 01edcf93..7322c277 100644 --- a/extensions/void/package.json +++ b/extensions/void/package.json @@ -10,6 +10,9 @@ "categories": [ "Other" ], + "enabledApiProposals": [ + "editorInsets" + ], "activationEvents": [], "main": "./out/extension/extension.js", "contributes": { diff --git a/extensions/void/src/extension/DiffProvider.ts b/extensions/void/src/extension/DiffProvider.ts index ca567b4c..9836dfde 100644 --- a/extensions/void/src/extension/DiffProvider.ts +++ b/extensions/void/src/extension/DiffProvider.ts @@ -3,6 +3,7 @@ import { findDiffs } from './findDiffs'; import { throttle } from 'lodash'; import { DiffArea, BaseDiff, Diff } from '../common/shared_types'; import { readFileContentOfUri } from './extensionLib/readFileContentOfUri'; +import { updateWebviewHTML } from './extensionLib/updateWebviewHTML'; const THROTTLE_TIME = 100 @@ -31,6 +32,8 @@ export class DiffProvider implements vscode.CodeLensProvider { private _diffareaidPool = 0 private _diffidPool = 0 + private _extensionUri: vscode.Uri + // used internally by vscode private _onDidChangeCodeLenses: vscode.EventEmitter = new vscode.EventEmitter(); // signals a UI refresh on .fire() events public readonly onDidChangeCodeLenses: vscode.Event = this._onDidChangeCodeLenses.event; @@ -42,7 +45,8 @@ export class DiffProvider implements vscode.CodeLensProvider { } // declared by us, registered with vscode.languages.registerCodeLensProvider() - constructor() { + constructor(context: vscode.ExtensionContext) { + this._extensionUri = context.extensionUri console.log('Creating DisplayChangesProvider') @@ -210,6 +214,21 @@ export class DiffProvider implements vscode.CodeLensProvider { ) ); + // update red highlighting + // this._diffsOfDocument[docUriStr] + // .filter(diff => diff.originalCode !== '') + // .forEach(diff => { + // const text = originalFile.split('\n').slice(diff.originalRange.start.line, diff.originalRange.start.line + 1).join('\n') + // const height = text.split('\n').length + // const line = diff.range.start.line - 1 + + // const inset = vscode.window.createWebviewTextEditorInset(editor, line, height); + // updateWebviewHTML(inset.webview, this._extensionUri, { jsOutLocation: 'dist/webviews/diffline/index.js', cssOutLocation: 'dist/webviews/styles.css' }, + // { text } + // ) + + + // }) // for each diffArea, highlight its sweepIndex in dark gray editor.setDecorations( @@ -234,8 +253,6 @@ export class DiffProvider implements vscode.CodeLensProvider { ) ) - // TODO update red highlighting - // this._diffsOfDocument[docUriStr].map(diff => diff.deletedCode) // update code lenses this._onDidChangeCodeLenses.fire() @@ -392,7 +409,7 @@ export class DiffProvider implements vscode.CodeLensProvider { // figure out where to highlight based on where the AI is in the stream right now, use the last diff in findDiffs to figure that out const diffs = findDiffs(originalDiffAreaCode, newDiffAreaCode) - const lastDiff = diffs[diffs.length - 1] ?? null + const lastDiff = diffs?.[diffs.length - 1] ?? null // these are two different coordinate systems - new and old line number let newFileEndLine: number // get new[0...newStoppingPoint] with line=newStoppingPoint highlighted diff --git a/extensions/void/src/extension/extension.ts b/extensions/void/src/extension/extension.ts index 042b5dac..cc7cbed6 100644 --- a/extensions/void/src/extension/extension.ts +++ b/extensions/void/src/extension/extension.ts @@ -83,7 +83,7 @@ export function activate(context: vscode.ExtensionContext) { ); // 3. Show an approve/reject codelens above each change - const diffProvider = new DiffProvider(); + const diffProvider = new DiffProvider(context); context.subscriptions.push(vscode.languages.registerCodeLensProvider('*', diffProvider)); // 4. Add approve/reject commands diff --git a/extensions/void/src/extension/extensionLib/updateWebviewHTML.ts b/extensions/void/src/extension/extensionLib/updateWebviewHTML.ts index 1957ac75..d237d4be 100644 --- a/extensions/void/src/extension/extensionLib/updateWebviewHTML.ts +++ b/extensions/void/src/extension/extensionLib/updateWebviewHTML.ts @@ -32,7 +32,7 @@ export const updateWebviewHTML = (webview: vscode.Webview, extensionUri: vscode. -
+
`; diff --git a/extensions/void/src/webviews/common/contextForProps.tsx b/extensions/void/src/webviews/common/contextForProps.tsx index 25f73abf..6775fcb1 100644 --- a/extensions/void/src/webviews/common/contextForProps.tsx +++ b/extensions/void/src/webviews/common/contextForProps.tsx @@ -1,22 +1,33 @@ import React, { ReactNode, createContext, useCallback, useContext, useEffect, useRef, useState, } from "react" -type PropsType = { [s: string]: any } | null - -type PropsValue = { props: PropsType } - -const PropsContext = createContext(undefined as unknown as PropsValue) +const PropsContext = createContext(undefined as unknown as any) // provider for whatever came in data-void-props -export function PropsProvider({ children, props }: { children: ReactNode, props: PropsType }) { +export function PropsProvider({ children, rootElement }: { children: ReactNode, rootElement: HTMLElement }) { + + const [props, setProps] = useState(null) + + // update props when rootElement changes + useEffect(() => { + let props = rootElement.getAttribute("data-void-props") + let propsObj: object | null = null + if (props !== null) { + propsObj = JSON.parse(decodeURIComponent(props)) + } + setProps(propsObj) + }, [rootElement]) + return ( - + {children} ) } -export function useVoidProps(): PropsValue { - const context = useContext(PropsContext) +export function useVoidProps(): T | null { + // context is the "value" from above + const context: T | null | undefined = useContext(PropsContext) + // only undefined if has no provider if (context === undefined) { throw new Error("useVoidProps missing Provider") } diff --git a/extensions/void/src/webviews/common/mount.tsx b/extensions/void/src/webviews/common/mount.tsx index 70ef66f6..a07b46b7 100644 --- a/extensions/void/src/webviews/common/mount.tsx +++ b/extensions/void/src/webviews/common/mount.tsx @@ -46,18 +46,12 @@ export const mount = (children: React.ReactNode) => { // mount the sidebar on the id="root" element const rootElement = document.getElementById("root")! - console.log("Void root Element:", rootElement) - - let props = rootElement.getAttribute("data-void-props") - let propsObj: object | null = null - if (props !== null) { - propsObj = JSON.parse(decodeURIComponent(props)) - } + // console.log("Void root Element:", rootElement) const content = (<> - + {children} @@ -69,4 +63,4 @@ export const mount = (children: React.ReactNode) => { const root = ReactDOM.createRoot(rootElement) root.render(content); -} \ No newline at end of file +} diff --git a/extensions/void/src/webviews/diffline/DiffLine.tsx b/extensions/void/src/webviews/diffline/DiffLine.tsx new file mode 100644 index 00000000..6fbe8b6c --- /dev/null +++ b/extensions/void/src/webviews/diffline/DiffLine.tsx @@ -0,0 +1,29 @@ +import React, { useState } from 'react'; +import { useOnVSCodeMessage } from '../common/getVscodeApi'; +import { useVoidProps } from '../common/contextForProps'; + + +type props = { + text: string +} + +export const DiffLine = () => { + + const props = useVoidProps() + + console.log('props!', props) + + if (!props) { + return null + } + + // eslint-disable-next-line react/prop-types + const text = props.text + + return <> +
+ {text} +
+ +}; + diff --git a/extensions/void/src/webviews/diffline/index.tsx b/extensions/void/src/webviews/diffline/index.tsx new file mode 100644 index 00000000..dc9a59b9 --- /dev/null +++ b/extensions/void/src/webviews/diffline/index.tsx @@ -0,0 +1,7 @@ +import React from "react" +import { mount } from "../common/mount" +import { DiffLine } from "./DiffLine" + +// this is the entry point that mounts diffline +mount() +