Extension for VSCode: Retrieve previous and current versions of a file

My current project involves creating a VSCode extension that needs to access the current open file and the same file from the previous git revision/commit. This is essentially what happens when you click the open changes button in vscode.

https://i.stack.imgur.com/KyGIP.png

I have attempted to utilize SCM and QuickDiffProvider, following the example provided in this sample extension. However, I am encountering an issue where it gives an error message "unable to resolve resource" when trying to open the old file in vscode.

https://i.stack.imgur.com/JpgJd.png


A snippet from extension.ts:

let folder: string = vscode.env.appRoot;
let scm: vscode.SourceControl | undefined;
if (vscode.workspace.workspaceFolders) {
    let rootUri = vscode.workspace.workspaceFolders[0].uri;
    scm = vscode.scm.createSourceControl("MyDiff", "MyDiff", rootUri);
    folder = rootUri.fsPath;
    var repo = new Repository(vscode.workspace.workspaceFolders[0]);
    scm.quickDiffProvider = repo;
    let changedResources = scm.createResourceGroup("workingTree", "Changes");
    // repo.getResourceStates().then((result) => {
    //     changedResources.resourceStates = result;
    // });
    // context.subscriptions.push(changedResources);
    var currentlyOpenTabfileUri = vscode.window.activeTextEditor?.document.uri;
    if(currentlyOpenTabfileUri){
        if(repo.provideOriginalResource){
            const repositoryUri = repo.provideOriginalResource(currentlyOpenTabfileUri, null);
            console.log(repositoryUri);
            console.log(currentlyOpenTabfileUri);
            try{
                vscode.commands.executeCommand('vscode.open', currentlyOpenTabfileUri);
                vscode.commands.executeCommand('vscode.open', repositoryUri);
                vscode.commands.executeCommand('vscode.diff', repositoryUri, currentlyOpenTabfileUri,  `Old - New`);
            }
            catch(err){
                console.error(err);
            }
        }
    }
}

Repository.ts:

export const JSFIDDLE_SCHEME = 'MyDiff';
import { QuickDiffProvider, Uri, CancellationToken, ProviderResult, WorkspaceFolder, workspace, window, env } from "vscode";
import * as path from 'path';


export class Repository implements QuickDiffProvider {

    constructor(private workspaceFolder: WorkspaceFolder) { }

    provideOriginalResource?(uri: Uri, token: CancellationToken|null): ProviderResult<Uri> {
        // converts the local file uri to jsfiddle:file.ext
        const relativePath = workspace.asRelativePath(uri.fsPath);
        return Uri.parse(`${JSFIDDLE_SCHEME}:${relativePath}`);
    }

    /**
     * Enumerates the resources under source control.
     */
    provideSourceControlledResources(): Uri[] {
        return [
            Uri.file(this.createLocalResourcePath('json'))
        ];
    }

    /**
     * Creates a local file path in the local workspace that corresponds to the part of the 
     * fiddle denoted by the given extension.
     *
     * @param extension fiddle part, which is also used as a file extension
     * @returns path of the locally cloned fiddle resource ending with the given extension
     */
    createLocalResourcePath(extension: string) {
        return path.join(this.workspaceFolder.uri.fsPath, extension);
    }
}

Debug Console Output:

Congratulations, your extension "vscode-test-diff" is now active!
h {scheme: 'MyDiff', authority: '', path: 'test', query: '', fragment: '', …}
h {scheme: 'file', authority: '', path: '/c:/dummy/test', query: '', fragment: '', …}

In essence, my goal is:
I aim to retrieve the file contents of the file in the left side view (old) and right side view (new), similar to how openChange functions in vscode. The objective is to implement a custom comparison method and store the result in HTML format instead of displaying it as a side-by-side comparison.

https://i.stack.imgur.com/lPaWx.png

Answer №1

After facing numerous challenges in finding an alternative solution for obtaining the difference of a file, I discovered that utilizing vscode.editors allows access to all open editors.

For instance: When using git diff, two editors are present (left: old and right: new). By employing the code below, we can retrieve the content of both versions.

if (editors.length === 2) {
    oldContent = editors[0].document.getText();
    newContent = editors[1].document.getText();
}

If Git Lens is employed, it enables retrieving the difference from previous commits using the same code, which proves to be advantageous for my extension.

The only drawback to this method is that it functions even if two editors are displayed in separate columns (a feature that suits my extension just fine).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering an Object Type Unknown error while working with Typescript and React

I am currently working on building a chatbox in React using TypeScript and Firebase. Below is the code for my Room and Message components: function ChatRoom() { const messagesRef = firestore.collection('messages'); const query = messagesRef.o ...

To ensure the next line only runs after the line above has finished executing, remember that the function is invoked in HTML

my.component.html <button (click)="refresh()">Refresh</button> my.component.ts refresh() { let self = this; self.isRefresh = true; //1st time self.getfun().then(() => { self.isRefresh = false; ...

Creating Apache Arrow vectors in TypeScript for writing data to a Table

Currently, I am in the process of creating a method that is designed to take a column of data, referred to as data: any[], and then pack it into an Arrow-typed Array Buffer for insertion into an Arrow table. To illustrate with an example, if we consider T ...

Can TypeScript be used to generate a union type that includes all the literal values from an input string array?

Is it feasible to create a function in TypeScript that takes an array of strings and returns a string union? Consider the following example function: function myfn(strs: string[]) { return strs[0]; } If I use this function like: myfn(['a', &a ...

VS Code does not support the usage of the pipenv .env file

Currently using VS Code 1.35.1 on ubuntu 16.04 with a Python 3.7.3 pipenv virtual environment, I am encountering an issue where my .env file is not being recognized to set environment variables. I'm seeking assistance in understanding how to grant my ...

Troubleshoot: Angular5 Service call not functioning properly when called in ngOnInit

Every time I go to the results component, the service inside ngOnInit behaves as expected. However, when I open the side menu, navigate to another page, and then return to the results page, the page fails to render the results. Instead, the ng-template is ...

Error: An unexpected character (.) was encountered | Building with npm has failed

When executing "npm run build", I encounter an error with the unexpected token (.) related to object values. Can someone assist me in resolving this issue? I am using tsc build for a react npm library. It seems like there might be a configuration problem ...

Utilizing material-ui with Autocomplete featuring various value and option types

In my code, I am looking to store only an option's ID in a value For autocomplete functionality, the value's type and the option's type need to be the same My solution was to change the value in onChange, which worked successfully However ...

How should we correctly import jquery.inputmask?

Struggling to import jquery.inputmask using webpack and TypeScript? Head over to this discussion at Issue #1115 : Here's how I configured things with jqlite: To import in your app, use the following code: import InputMask from 'inputmask&apos ...

How can I update the image source using Angular?

<div class="float-right"> <span class="language dashboard" data-toggle="dropdown"> <img class="current" src="us-flag.png" /> </span> <div class="dropdown dashboar ...

What is the best way to utilize ngStyle in combination with Interpolation?

Within my application, I am faced with a challenge involving two slide bars that generate values ranging from 1 to 100. Based on these generated values, I aim to adjust the margin of a div element in accordance with the percentage output. Despite conductin ...

Display embedded ng-template in Angular 6

I've got a template set up like this <ng-template #parent> <ng-template #child1> child 1 </ng-template> <ng-template #child2> child 2 </ng-template> </ng-template> Anyone know how t ...

Implementing cursor-based pagination in Next.js API Route with Prisma and leveraging the power of useSWRInfinite

I am working on implementing cursor-based pagination for a table of posts using Next.js API Route, Prisma, and useSWRInfinite. Currently, I am fetching the ten most recent posts with Prisma in a Next.js API Route and displaying them using useSWR, sorted b ...

In TypeScript, combining the numbers 0 and 1 results in the value 01

I am in the process of developing a Shopping Card feature. private _card: Map<Product, number> = new Map<Product, number>(); ... addToCard(prod: Product, amount: number = 1): void { const totalAmount: number = this._card.get(prod) + amou ...

A guide to retrieving the types of optional properties within a class or interface using Typescript

class Data { ID: number; Activity?: string; public getDataType(name: string) { return typeof this[name]; } constructor() { } } let _data = new Data() _data.ID = 5 console.log(_data.getDataType("ID")) // Retu ...

When publishing, TypeScript-compiled JS files fail to be included, even though they are included during the build process in Debug and Release modes

My .NET MAUI project includes TypeScript files in the Scripts\scriptfiles.ts folder, which are compiled into wwwroot\js\scriptfiles.js. Everything functions properly until my client attempts to publish it, at which point all script files go ...

How to toggle code block visibility in Angular's ngOnInit() method

I'm currently analyzing different design patterns to optimize the number of REST calls when implementing a 'save while typing feature'. To provide a general overview, in my ngOnInit() function, I have included the following code snippet (wit ...

The absence of the @Injectable annotation is causing an issue when importing a JSON

I am currently in the process of integrating a JSON file into my service by using a @inject() tag within the constructor. Below is the code snippet I am working with. DependencyInjectionContainer.ts import { Container, decorate, injectable } from "invers ...

Is there a way to render a component without having to render AppComponent constantly?

I am looking to display two components (AppComponent and UserComponent) without constantly displaying AppComponent. Here's how my code is structured: app.routing.module.ts const routes: Routes = [ { path: '', component: AppComponent ...

Employing distinct techniques for a union-typed variable in TypeScript

I'm currently in the process of converting a JavaScript library to TypeScript. One issue I've encountered is with a variable that can be either a boolean or an array. This variable cannot be separated into two different variables because it&apos ...