Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 60 additions & 2 deletions extensions/git/src/gitEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import { CancellationToken, DocumentLink, DocumentLinkProvider, l10n, Range, TabInputText, TextDocument, Uri, window, workspace } from 'vscode';
import { CancellationToken, CodeLens, CodeLensProvider, DocumentLink, DocumentLinkProvider, Event, EventEmitter, l10n, languages, Range, TabInputText, TextDocument, Uri, window, workspace } from 'vscode';
import { IIPCHandler, IIPCServer } from './ipc/ipcServer';
import { ITerminalEnvironmentProvider } from './terminal';
import { EmptyDisposable, IDisposable } from './util';
Expand All @@ -21,7 +21,7 @@ export class GitEditor implements IIPCHandler, ITerminalEnvironmentProvider {

readonly featureDescription = 'git editor';

constructor(ipc?: IIPCServer) {
constructor(private readonly _codeLensProvider: GitEditorCodeLensProvider, ipc?: IIPCServer) {
if (ipc) {
this.disposable = ipc.registerHandler('git-editor', this);
}
Expand All @@ -40,9 +40,12 @@ export class GitEditor implements IIPCHandler, ITerminalEnvironmentProvider {
const doc = await workspace.openTextDocument(uri);
await window.showTextDocument(doc, { preview: false });

this._codeLensProvider.addUri(uri);

return new Promise((c) => {
const onDidClose = window.tabGroups.onDidChangeTabs(async (tabs) => {
if (tabs.closed.some(t => t.input instanceof TabInputText && t.input.uri.toString() === uri.toString())) {
this._codeLensProvider.removeUri(uri);
onDidClose.dispose();
return c(true);
}
Expand All @@ -68,6 +71,61 @@ export class GitEditor implements IIPCHandler, ITerminalEnvironmentProvider {
}
}

export class GitEditorCodeLensProvider implements CodeLensProvider, IDisposable {

private readonly _activeUris = new Set<string>();
private readonly _onDidChangeCodeLenses = new EventEmitter<void>();
private readonly _disposables: IDisposable[] = [];

readonly onDidChangeCodeLenses: Event<void> = this._onDidChangeCodeLenses.event;

constructor() {
this._disposables.push(
languages.registerCodeLensProvider({ language: 'git-commit' }, this),
this._onDidChangeCodeLenses
);
}

addUri(uri: Uri): void {
this._activeUris.add(uri.toString());
this._onDidChangeCodeLenses.fire();
}

removeUri(uri: Uri): void {
this._activeUris.delete(uri.toString());
this._onDidChangeCodeLenses.fire();
}

provideCodeLenses(document: TextDocument, _token: CancellationToken): CodeLens[] {
if (!this._activeUris.has(document.uri.toString())) {
return [];
}

const range = new Range(0, 0, 0, 0);

const commitCommand = {
command: 'git.commitMessageAccept',
title: l10n.t('$(check) Commit'),
arguments: [document.uri]
};

const discardCommand = {
command: 'git.commitMessageDiscard',
title: l10n.t('$(x) Cancel'),
arguments: [document.uri]
};

return [
new CodeLens(range, commitCommand),
new CodeLens(range, discardCommand),
];
}

dispose(): void {
this._disposables.forEach(d => d.dispose());
}
}

export class GitEditorDocumentLinkProvider implements DocumentLinkProvider {
private readonly _regex = /^#\s+(modified|new file|deleted|renamed|copied|type change):\s+(?<file1>.*?)(?:\s+->\s+(?<file2>.*))*$/gm;

Expand Down
7 changes: 5 additions & 2 deletions extensions/git/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { GitTimelineProvider } from './timelineProvider';
import { registerAPICommands } from './api/api1';
import { TerminalEnvironmentManager, TerminalShellExecutionManager } from './terminal';
import { createIPCServer, IPCServer } from './ipc/ipcServer';
import { GitEditor, GitEditorDocumentLinkProvider } from './gitEditor';
import { GitEditor, GitEditorCodeLensProvider, GitEditorDocumentLinkProvider } from './gitEditor';
import { GitPostCommitCommandsProvider } from './postCommitCommands';
import { GitEditSessionIdentityProvider } from './editSessionIdentityProvider';
import { GitCommitInputBoxCodeActionsProvider, GitCommitInputBoxDiagnosticsManager } from './diagnostics';
Expand Down Expand Up @@ -76,7 +76,10 @@ async function createModel(context: ExtensionContext, logger: LogOutputChannel,
const askpass = new Askpass(ipcServer, logger, askpassPaths);
disposables.push(askpass);

const gitEditor = new GitEditor(ipcServer);
const gitEditorCodeLensProvider = new GitEditorCodeLensProvider();
disposables.push(gitEditorCodeLensProvider);

const gitEditor = new GitEditor(gitEditorCodeLensProvider, ipcServer);
disposables.push(gitEditor);

const environment = { ...askpass.getEnv(), ...gitEditor.getEnv(), ...ipcServer?.getEnv() };
Expand Down