|
3 | 3 | * Licensed under the MIT License. See License.txt in the project root for license information.
|
4 | 4 | *--------------------------------------------------------------------------------------------*/
|
5 | 5 | import * as path from 'path';
|
6 |
| -import { TabInputText, Uri, window, workspace } from 'vscode'; |
| 6 | +import { CancellationToken, DocumentLink, DocumentLinkProvider, l10n, Range, TabInputText, TextDocument, Uri, window, workspace } from 'vscode'; |
7 | 7 | import { IIPCHandler, IIPCServer } from './ipc/ipcServer';
|
8 | 8 | import { ITerminalEnvironmentProvider } from './terminal';
|
9 | 9 | import { EmptyDisposable, IDisposable } from './util';
|
| 10 | +import { Model } from './model'; |
| 11 | +import { Repository } from './repository'; |
10 | 12 |
|
11 | 13 | interface GitEditorRequest {
|
12 | 14 | commitMessagePath?: string;
|
@@ -63,3 +65,51 @@ export class GitEditor implements IIPCHandler, ITerminalEnvironmentProvider {
|
63 | 65 | this.disposable.dispose();
|
64 | 66 | }
|
65 | 67 | }
|
| 68 | + |
| 69 | +export class GitEditorDocumentLinkProvider implements DocumentLinkProvider { |
| 70 | + private readonly _regex = /^#\s+(modified|new file|deleted|renamed|copied|type change):\s+(?<file1>.*?)(?:\s+->\s+(?<file2>.*))*$/gm; |
| 71 | + |
| 72 | + constructor(private readonly _model: Model) { } |
| 73 | + |
| 74 | + provideDocumentLinks(document: TextDocument, token: CancellationToken): DocumentLink[] { |
| 75 | + if (token.isCancellationRequested) { |
| 76 | + return []; |
| 77 | + } |
| 78 | + |
| 79 | + const repository = this._model.getRepository(document.uri); |
| 80 | + if (!repository) { |
| 81 | + return []; |
| 82 | + } |
| 83 | + |
| 84 | + const links: DocumentLink[] = []; |
| 85 | + for (const match of document.getText().matchAll(this._regex)) { |
| 86 | + if (!match.groups) { |
| 87 | + continue; |
| 88 | + } |
| 89 | + |
| 90 | + const { file1, file2 } = match.groups; |
| 91 | + |
| 92 | + if (file1) { |
| 93 | + links.push(this._createDocumentLink(repository, document, match, file1)); |
| 94 | + } |
| 95 | + if (file2) { |
| 96 | + links.push(this._createDocumentLink(repository, document, match, file2)); |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + return links; |
| 101 | + } |
| 102 | + |
| 103 | + private _createDocumentLink(repository: Repository, document: TextDocument, match: RegExpExecArray, file: string): DocumentLink { |
| 104 | + const startIndex = match[0].indexOf(file); |
| 105 | + const startPosition = document.positionAt(match.index + startIndex); |
| 106 | + const endPosition = document.positionAt(match.index + startIndex + file.length); |
| 107 | + |
| 108 | + const documentLink = new DocumentLink( |
| 109 | + new Range(startPosition, endPosition), |
| 110 | + Uri.file(path.join(repository.root, file))); |
| 111 | + documentLink.tooltip = l10n.t('Open File'); |
| 112 | + |
| 113 | + return documentLink; |
| 114 | + } |
| 115 | +} |
0 commit comments