Skip to content

Extension Integration: Source Control Management #1011

@bryphe

Description

@bryphe

One feature we're sorely lacking is managing source control from the editor - showing 'diffs' on the editor surface, show modified / staged files in the file explorer, and managing Git or other source-control management workflow (like merging or rebasing).

The VSCode extension host actually provides a lot of functionality for us that we should be integrating with - it handles git out-of-the-box, but it can also handle other source control management tools via extensions.

It then bundles these interfaces into a consistent interface for the editor via the extension host protocol:

The ExtHostSCMShape is the API we call to from Onivim 2:

export interface ExtHostSCMShape {
	$provideOriginalResource(sourceControlHandle: number, uri: UriComponents, token: CancellationToken): Promise<UriComponents | null>;
	$onInputBoxValueChange(sourceControlHandle: number, value: string): void;
	$executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): Promise<void>;
	$validateInput(sourceControlHandle: number, value: string, cursorPosition: number): Promise<[string, number] | undefined>;
	$setSelectedSourceControls(selectedSourceControlHandles: number[]): Promise<void>;
}

https://github.com/onivim/vscode-exthost/blob/a25f426a04fe427beab7465be660f89a794605b5/src/vs/workbench/api/node/extHost.protocol.ts#L1019

And the MainThreadSCMShape is the API we are expected to implement in Onivim 2 (calls come from the extension host -> editor):

export interface SCMProviderFeatures {
	hasQuickDiffProvider?: boolean;
	count?: number;
	commitTemplate?: string;
	acceptInputCommand?: modes.Command;
	statusBarCommands?: CommandDto[];
}

export interface SCMGroupFeatures {
	hideWhenEmpty?: boolean;
}

export type SCMRawResource = [
	number /*handle*/,
	UriComponents /*resourceUri*/,
	string[] /*icons: light, dark*/,
	string /*tooltip*/,
	boolean /*strike through*/,
	boolean /*faded*/,

	string | undefined /*source*/,
	string | undefined /*letter*/,
	ThemeColor | null /*color*/
];

export type SCMRawResourceSplice = [
	number /* start */,
	number /* delete count */,
	SCMRawResource[]
];

export type SCMRawResourceSplices = [
	number, /*handle*/
	SCMRawResourceSplice[]
];

export interface MainThreadSCMShape extends IDisposable {
	$registerSourceControl(handle: number, id: string, label: string, rootUri: UriComponents | undefined): void;
	$updateSourceControl(handle: number, features: SCMProviderFeatures): void;
	$unregisterSourceControl(handle: number): void;

	$registerGroup(sourceControlHandle: number, handle: number, id: string, label: string): void;
	$updateGroup(sourceControlHandle: number, handle: number, features: SCMGroupFeatures): void;
	$updateGroupLabel(sourceControlHandle: number, handle: number, label: string): void;
	$unregisterGroup(sourceControlHandle: number, handle: number): void;

	$spliceResourceStates(sourceControlHandle: number, splices: SCMRawResourceSplices[]): void;

	$setInputBoxValue(sourceControlHandle: number, value: string): void;
	$setInputBoxPlaceholder(sourceControlHandle: number, placeholder: string): void;
	$setInputBoxVisibility(sourceControlHandle: number, visible: boolean): void;
	$setValidationProviderIsEnabled(sourceControlHandle: number, enabled: boolean): void;
}

https://github.com/onivim/vscode-exthost/blob/a25f426a04fe427beab7465be660f89a794605b5/src/vs/workbench/api/node/extHost.protocol.ts#L645

Once we have parity with VSCode integration - I'd like to exploring sort of next level experiences with source control. Some other sources of inspiration for version control:

  • Magit has a lot to learn from!
  • vim-fugitive is a very popular Vim plugin for working with Git

But we'll track these efforts in a new meta issue, once this is done.

The high-level work involved is:

  • Bring in the built-in git extension
  • UI: Augment the EditorSurface to allow showing diff markers
  • Wiring up initial extension APIs:
    • Handle the register/update/unregister` requests
    • Handle the spliceResourceStates request, which looks like it gives some diff info
  • State: Model the SCM values (the resource splices) in an appropriate form in our state model.
  • UI: Wire up the SCM values into our EditorSurface, so we show diff splices
  • UI: Wire up the SCM values into our file explorer, so we can show source control state
  • UI: Create a sidebar pane for source-control management (SCM)
  • Wiring up 'pane' integration
    • Handle the setInputBox interop
  • Extend the editor surface to support showing diffs

Will be tracking progress towards this here: https://github.com/onivim/oni2/projects/12

Associated PRs:

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-extensionArea: Extension/plugin integration, vscode or VimLA-scmArea: Source Control Management (Version Control Integration)enhancementNew feature or requestmetaA big-picture issue, often collecting a number of other issues for discussing overarching solutions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions