mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
add files to make native insets work! #124
This commit is contained in:
parent
d7c00addd5
commit
5acc53311d
8 changed files with 323 additions and 3 deletions
|
|
@ -25,6 +25,13 @@ declare module 'vscode' {
|
|||
}
|
||||
}
|
||||
|
||||
// this comes from vscode.d.ts
|
||||
declare module 'vscode' {
|
||||
export namespace languages {
|
||||
export function addInlineDiff(editor: vscode.TextEditor, originalText: string, modifiedRange: Range): void;
|
||||
}
|
||||
}
|
||||
|
||||
const roundRangeToLines = (selection: vscode.Selection) => {
|
||||
let endLine = selection.end.character === 0 ? selection.end.line - 1 : selection.end.line // e.g. if the user triple clicks, it selects column=0, line=line -> column=0, line=line+1
|
||||
return new vscode.Range(selection.start.line, 0, endLine, Number.MAX_SAFE_INTEGER)
|
||||
|
|
@ -62,6 +69,9 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
|
||||
const { selectionStr, filePath } = getSelection(editor)
|
||||
|
||||
vscode.languages.addInlineDiff(editor, 'oldText', editor.selection)
|
||||
|
||||
|
||||
// send message to the webview (Sidebar.tsx)
|
||||
sidebarWebviewProvider.webview.then(webview => webview.postMessage({ type: 'ctrl+l', selection: { selectionStr, filePath } } satisfies MessageToSidebar));
|
||||
})
|
||||
|
|
|
|||
115
src/vs/editor/browser/services/inlineDiffService.ts
Normal file
115
src/vs/editor/browser/services/inlineDiffService.ts
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
// This file was added by the Void team
|
||||
|
||||
// src/vs/editor/browser/services/inlineDiffService.ts
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
import { registerSingleton, InstantiationType } from '../../../platform/instantiation/common/extensions.js';
|
||||
import { createDecorator } from '../../../platform/instantiation/common/instantiation.js';
|
||||
import { IModelDecorationOptions, IModelDeltaDecoration } from '../../common/model.js';
|
||||
import { ICodeEditor, IViewZone } from '../editorBrowser.js';
|
||||
import { IRange } from '../../common/core/range.js';
|
||||
|
||||
|
||||
export interface IInlineDiffService {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
addDiff(editor: ICodeEditor, originalText: string, modifiedRange: IRange): void;
|
||||
removeDiffs(editor: ICodeEditor): void;
|
||||
}
|
||||
|
||||
export const IInlineDiffService = createDecorator<IInlineDiffService>('inlineDiffService');
|
||||
|
||||
class InlineDiffService extends Disposable implements IInlineDiffService {
|
||||
private readonly _diffDecorations = new Map<ICodeEditor, string[]>();
|
||||
private readonly _diffZones = new Map<ICodeEditor, string[]>();
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private static readonly ADDED_DECORATION: IModelDecorationOptions = {
|
||||
className: 'inline-diff-added',
|
||||
description: 'inline-diff-added',
|
||||
isWholeLine: false,
|
||||
minimap: {
|
||||
color: { id: 'minimapGutter.addedBackground' },
|
||||
position: 2
|
||||
},
|
||||
overviewRuler: {
|
||||
color: { id: 'editorOverviewRuler.addedForeground' },
|
||||
position: 7
|
||||
}
|
||||
};
|
||||
|
||||
constructor(
|
||||
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
public addDiff: IInlineDiffService['addDiff'] = (editor, originalText, modifiedRange) => {
|
||||
|
||||
// Clear existing diffs
|
||||
this.removeDiffs(editor);
|
||||
|
||||
// Add decoration for modified text
|
||||
const decorations: IModelDeltaDecoration[] = [{
|
||||
range: modifiedRange,
|
||||
options: InlineDiffService.ADDED_DECORATION
|
||||
}];
|
||||
|
||||
const newDecorations = editor.deltaDecorations([], decorations);
|
||||
this._diffDecorations.set(editor, newDecorations);
|
||||
|
||||
// Add view zone for original text
|
||||
editor.changeViewZones(accessor => {
|
||||
const domNode = document.createElement('div');
|
||||
domNode.className = 'inline-diff-deleted monaco-editor';
|
||||
|
||||
// Create inner container for proper padding
|
||||
const innerContainer = document.createElement('div');
|
||||
innerContainer.className = 'view-line';
|
||||
innerContainer.textContent = originalText;
|
||||
domNode.appendChild(innerContainer);
|
||||
|
||||
const viewZone: IViewZone = {
|
||||
afterLineNumber: modifiedRange.startLineNumber - 1,
|
||||
heightInLines: originalText.split('\n').length,
|
||||
domNode: domNode,
|
||||
suppressMouseDown: true,
|
||||
marginDomNode: this.createGutterElement(editor)
|
||||
};
|
||||
|
||||
const zoneId = accessor.addZone(viewZone);
|
||||
this._diffZones.set(editor, [zoneId]);
|
||||
});
|
||||
}
|
||||
|
||||
private createGutterElement(editor: ICodeEditor): HTMLElement {
|
||||
const gutterDiv = document.createElement('div');
|
||||
gutterDiv.className = 'inline-diff-gutter';
|
||||
gutterDiv.innerHTML = '<div class="inline-diff-deleted-gutter">-</div>';
|
||||
return gutterDiv;
|
||||
}
|
||||
|
||||
public removeDiffs(editor: ICodeEditor): void {
|
||||
// Clear decorations
|
||||
const decorationIds = this._diffDecorations.get(editor) || [];
|
||||
editor.deltaDecorations(decorationIds, []);
|
||||
this._diffDecorations.delete(editor);
|
||||
|
||||
// Clear view zones
|
||||
editor.changeViewZones(accessor => {
|
||||
const zoneIds = this._diffZones.get(editor) || [];
|
||||
zoneIds.forEach(id => accessor.removeZone(id));
|
||||
});
|
||||
this._diffZones.delete(editor);
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
this._diffDecorations.clear();
|
||||
this._diffZones.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Register the service
|
||||
registerSingleton(IInlineDiffService, InlineDiffService, InstantiationType.Eager);
|
||||
|
||||
|
||||
|
|
@ -425,3 +425,27 @@
|
|||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Void added this: */
|
||||
.inline-diff-deleted {
|
||||
background-color: var(--vscode-diffEditor-removedTextBackground);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.inline-diff-added {
|
||||
background-color: var(--vscode-diffEditor-insertedTextBackground);
|
||||
}
|
||||
|
||||
.inline-diff-gutter {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.inline-diff-deleted-gutter {
|
||||
opacity: 0.7;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.view-line {
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
|
|
|||
82
src/vs/workbench/api/browser/mainThreadInlineDiff.ts
Normal file
82
src/vs/workbench/api/browser/mainThreadInlineDiff.ts
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
// Void created this file
|
||||
// it comes from mainThreadCodeInsets.ts
|
||||
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
import { ICodeEditorService } from '../../../editor/browser/services/codeEditorService.js';
|
||||
import { MainContext, MainThreadInlineDiffShape } from '../common/extHost.protocol.js';
|
||||
import { IInlineDiffService } from '../../../editor/browser/services/inlineDiffService.js';
|
||||
import { ICodeEditor } from '../../../editor/browser/editorBrowser.js';
|
||||
import { IRange } from '../../../editor/common/core/range.js';
|
||||
import { extHostNamedCustomer, IExtHostContext } from '../../services/extensions/common/extHostCustomers.js';
|
||||
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadInlineDiff)
|
||||
export class MainThreadInlineDiff extends Disposable implements MainThreadInlineDiffShape {
|
||||
|
||||
// private readonly _proxy: ExtHostEditorInsetsShape;
|
||||
// private readonly _disposables = new DisposableStore();
|
||||
|
||||
constructor(
|
||||
context: IExtHostContext,
|
||||
@IInlineDiffService private readonly _inlineDiff: IInlineDiffService,
|
||||
@ICodeEditorService private readonly _editorService: ICodeEditorService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
// this._proxy = context.getProxy(ExtHostContext.ExtHostEditorInsets);
|
||||
|
||||
// dispose(): void {
|
||||
// this._disposables.dispose();
|
||||
// }
|
||||
|
||||
$addDiff(editorId: string, originalText: string, range: IRange): void {
|
||||
|
||||
let editor: ICodeEditor | undefined;
|
||||
editorId = editorId.substr(0, editorId.indexOf(',')); //todo@jrieken HACK
|
||||
|
||||
for (const candidate of this._editorService.listCodeEditors()) {
|
||||
if (candidate.getId() === editorId
|
||||
// && candidate.hasModel() && isEqual(candidate.getModel().uri, URI.revive(uri))
|
||||
) {
|
||||
editor = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!editor) {
|
||||
// setTimeout(() => this._proxy.$onDidDispose(editorId));
|
||||
return;
|
||||
}
|
||||
|
||||
this._inlineDiff.addDiff(editor, originalText, range)
|
||||
|
||||
|
||||
// return editor
|
||||
|
||||
// const disposables = new DisposableStore();
|
||||
|
||||
// const remove = () => {
|
||||
// disposables.dispose();
|
||||
// this._proxy.$onDidDispose(handle);
|
||||
// this._insets.delete(handle);
|
||||
// };
|
||||
|
||||
// disposables.add(editor.onDidChangeModel(remove));
|
||||
// disposables.add(editor.onDidDispose(remove));
|
||||
|
||||
}
|
||||
|
||||
// $disposeEditorInset(handle: number): void {
|
||||
// const inset = this.getInset(handle);
|
||||
// this._insets.delete(handle);
|
||||
// inset.dispose();
|
||||
// }
|
||||
|
||||
// private getInset(handle: number): EditorWebviewZone {
|
||||
// const inset = this._insets.get(handle);
|
||||
// if (!inset) {
|
||||
// throw new Error('Unknown inset');
|
||||
// }
|
||||
// return inset;
|
||||
// }
|
||||
}
|
||||
|
|
@ -109,6 +109,7 @@ import { ProxyIdentifier } from '../../services/extensions/common/proxyIdentifie
|
|||
import { ExcludeSettingOptions, TextSearchCompleteMessageType, TextSearchContextNew, TextSearchMatchNew } from '../../services/search/common/searchExtTypes.js';
|
||||
import type * as vscode from 'vscode';
|
||||
import { ExtHostCodeMapper } from './extHostCodeMapper.js';
|
||||
import { ExtHostInlineDiff } from './extHostInlineDiff.js';
|
||||
|
||||
export interface IExtensionRegistries {
|
||||
mine: ExtensionDescriptionRegistry;
|
||||
|
|
@ -221,6 +222,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
const extHostSpeech = rpcProtocol.set(ExtHostContext.ExtHostSpeech, new ExtHostSpeech(rpcProtocol));
|
||||
const extHostEmbeddings = rpcProtocol.set(ExtHostContext.ExtHostEmbeddings, new ExtHostEmbeddings(rpcProtocol));
|
||||
|
||||
// Void added this:
|
||||
const extHostInlineDiff = rpcProtocol.set(ExtHostContext.ExtHostInlineDiff, new ExtHostInlineDiff(rpcProtocol.getProxy(MainContext.MainThreadInlineDiff), extHostEditors));
|
||||
|
||||
// Check that no named customers are missing
|
||||
const expected = Object.values<ProxyIdentifier<any>>(ExtHostContext);
|
||||
rpcProtocol.assertRegistered(expected);
|
||||
|
|
@ -519,6 +523,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
|
||||
// namespace: languages
|
||||
const languages: typeof vscode.languages = {
|
||||
|
||||
createDiagnosticCollection(name?: string): vscode.DiagnosticCollection {
|
||||
return extHostDiagnostics.createDiagnosticCollection(extension.identifier, name);
|
||||
},
|
||||
|
|
@ -553,6 +558,11 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider);
|
||||
},
|
||||
|
||||
// Void added addInlineDiff here:
|
||||
addInlineDiff(editor: vscode.TextEditor, originalText: string, modifiedRange: vscode.Range): void {
|
||||
extHostInlineDiff.addDiff(editor, originalText, modifiedRange)
|
||||
},
|
||||
|
||||
// Void added this (I think will need to add this back when add ctrl+K)
|
||||
// registerVoidCtrlKProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable {
|
||||
// return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider);
|
||||
|
|
|
|||
|
|
@ -2984,7 +2984,10 @@ export const MainContext = {
|
|||
MainThreadTesting: createProxyIdentifier<MainThreadTestingShape>('MainThreadTesting'),
|
||||
MainThreadLocalization: createProxyIdentifier<MainThreadLocalizationShape>('MainThreadLocalizationShape'),
|
||||
MainThreadAiRelatedInformation: createProxyIdentifier<MainThreadAiRelatedInformationShape>('MainThreadAiRelatedInformation'),
|
||||
MainThreadAiEmbeddingVector: createProxyIdentifier<MainThreadAiEmbeddingVectorShape>('MainThreadAiEmbeddingVector')
|
||||
MainThreadAiEmbeddingVector: createProxyIdentifier<MainThreadAiEmbeddingVectorShape>('MainThreadAiEmbeddingVector'),
|
||||
|
||||
// Void added this:
|
||||
MainThreadInlineDiff: createProxyIdentifier<MainThreadInlineDiffShape>('MainThreadInlineDiff'),
|
||||
};
|
||||
|
||||
export const ExtHostContext = {
|
||||
|
|
@ -3055,5 +3058,17 @@ export const ExtHostContext = {
|
|||
ExtHostTimeline: createProxyIdentifier<ExtHostTimelineShape>('ExtHostTimeline'),
|
||||
ExtHostTesting: createProxyIdentifier<ExtHostTestingShape>('ExtHostTesting'),
|
||||
ExtHostTelemetry: createProxyIdentifier<ExtHostTelemetryShape>('ExtHostTelemetry'),
|
||||
ExtHostLocalization: createProxyIdentifier<ExtHostLocalizationShape>('ExtHostLocalization')
|
||||
ExtHostLocalization: createProxyIdentifier<ExtHostLocalizationShape>('ExtHostLocalization'),
|
||||
|
||||
// Void added this:
|
||||
ExtHostInlineDiff: createProxyIdentifier<ExtHostInlineDiffShape>('ExtHostInlineDiff'), // Void added this
|
||||
};
|
||||
|
||||
|
||||
// Void added these:
|
||||
export interface ExtHostInlineDiffShape {
|
||||
$onDidDispose(handle: number): void;
|
||||
}
|
||||
export interface MainThreadInlineDiffShape {
|
||||
$addDiff(editorId: string, originalText: string, range: IRange): void;
|
||||
}
|
||||
|
|
|
|||
62
src/vs/workbench/api/common/extHostInlineDiff.ts
Normal file
62
src/vs/workbench/api/common/extHostInlineDiff.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// This file was created by Void
|
||||
// reference extHostCodeInsets.ts
|
||||
|
||||
import { Emitter } from '../../../base/common/event.js';
|
||||
import { DisposableStore } from '../../../base/common/lifecycle.js';
|
||||
import { ExtHostInlineDiffShape, MainThreadInlineDiffShape } from './extHost.protocol.js';
|
||||
import * as vscode from 'vscode'
|
||||
import { ExtHostTextEditor } from './extHostTextEditor.js';
|
||||
import { ExtHostEditors } from './extHostTextEditors.js';
|
||||
import { Range } from '../../../workbench/api/common/extHostTypeConverters.js'
|
||||
|
||||
export class ExtHostInlineDiff implements ExtHostInlineDiffShape {
|
||||
|
||||
private readonly _disposables = new DisposableStore();
|
||||
private _insets = new Map<number, { editor: vscode.TextEditor; inset: vscode.WebviewEditorInset; onDidReceiveMessage: Emitter<any> }>();
|
||||
|
||||
constructor(
|
||||
private readonly _proxy: MainThreadInlineDiffShape,
|
||||
private readonly _editors: ExtHostEditors,
|
||||
) { }
|
||||
|
||||
|
||||
dispose(): void {
|
||||
this._insets.forEach(value => value.inset.dispose());
|
||||
this._disposables.dispose();
|
||||
}
|
||||
|
||||
|
||||
addDiff(editor: vscode.TextEditor, originalText: string, modifiedRange: vscode.Range) {
|
||||
|
||||
let apiEditor: ExtHostTextEditor | undefined;
|
||||
for (const candidate of this._editors.getVisibleTextEditors(true)) {
|
||||
if (candidate.value === editor) {
|
||||
apiEditor = <ExtHostTextEditor>candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!apiEditor) {
|
||||
throw new Error('not a visible editor');
|
||||
}
|
||||
|
||||
const id = apiEditor.id;
|
||||
// let uri = apiEditor.value.document.uri;
|
||||
|
||||
// convert to IRange
|
||||
const range = Range.from(modifiedRange)
|
||||
|
||||
this._proxy.$addDiff(id, originalText, range)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// main thread calls this when disposes diff with this particular handle
|
||||
$onDidDispose(handle: number): void {
|
||||
const value = this._insets.get(handle);
|
||||
if (value) {
|
||||
value.inset.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
4
src/vscode-dts/vscode.d.ts
vendored
4
src/vscode-dts/vscode.d.ts
vendored
|
|
@ -4,7 +4,6 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'vscode' {
|
||||
|
||||
/**
|
||||
* The version of the editor.
|
||||
*/
|
||||
|
|
@ -14074,6 +14073,9 @@ declare module 'vscode' {
|
|||
*/
|
||||
export namespace languages {
|
||||
|
||||
/** Void added this: */
|
||||
export function addInlineDiff(editor: TextEditor, originalText: string, modifiedRange: Range): void;
|
||||
|
||||
/**
|
||||
* Return the identifiers of all known languages.
|
||||
* @returns Promise resolving to an array of identifier strings.
|
||||
|
|
|
|||
Loading…
Reference in a new issue