Skip to content

Commit b7c553b

Browse files
authored
Support creating issues within editor
Fixes microsoft#1713
1 parent 5c89184 commit b7c553b

File tree

2 files changed

+28
-22
lines changed

2 files changed

+28
-22
lines changed

src/issues/issueFeatureRegistrar.ts

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import { ITelemetry } from '../common/telemetry';
2424
const ISSUE_COMPLETIONS_CONFIGURATION = 'issueCompletions.enabled';
2525
const USER_COMPLETIONS_CONFIGURATION = 'userCompletions.enabled';
2626

27+
const NEW_ISSUE_SCHEME = 'newIssue'
28+
2729
export class IssueFeatureRegistrar implements vscode.Disposable {
2830
private _stateManager: StateManager;
2931
private createIssueInfo: { document: vscode.TextDocument, newIssue: NewIssue | undefined, assignee: string | undefined, lineNumber: number | undefined, insertIndex: number | undefined } | undefined;
@@ -180,7 +182,7 @@ export class IssueFeatureRegistrar implements vscode.Disposable {
180182
this.context.subscriptions.push(vscode.languages.registerHoverProvider('*', new IssueHoverProvider(this.manager, this._stateManager, this.context, this.telemetry)));
181183
this.context.subscriptions.push(vscode.languages.registerHoverProvider('*', new UserHoverProvider(this.manager, this.telemetry)));
182184
this.context.subscriptions.push(vscode.languages.registerCodeActionsProvider('*', new IssueTodoProvider(this.context)));
183-
this.context.subscriptions.push(vscode.workspace.registerFileSystemProvider('newIssue', new IssueFileSystemProvider()));
185+
this.context.subscriptions.push(vscode.workspace.registerFileSystemProvider(NEW_ISSUE_SCHEME, new IssueFileSystemProvider()));
184186
});
185187
}
186188

@@ -223,20 +225,12 @@ export class IssueFeatureRegistrar implements vscode.Disposable {
223225
}
224226

225227
async createIssue() {
226-
try {
227-
const defaults = await this.manager.getPullRequestDefaults();
228-
return vscode.env.openExternal(vscode.Uri.parse(`https://github.com/${defaults.owner}/${defaults.repo}/issues/new/choose`));
229-
} catch (e) {
230-
vscode.window.showErrorMessage('Unable to determine where to create the issue.');
231-
}
228+
return this.makeNewIssueFile();
232229
}
233230

234231
async createIssueFromFile() {
235-
if (this.createIssueInfo === undefined) {
236-
return;
237-
}
238232
let text: string;
239-
if (!vscode.window.activeTextEditor) {
233+
if (!vscode.window.activeTextEditor || (vscode.window.activeTextEditor.document.uri.scheme !== NEW_ISSUE_SCHEME)) {
240234
return;
241235
}
242236
text = vscode.window.activeTextEditor.document.getText();
@@ -259,9 +253,9 @@ export class IssueFeatureRegistrar implements vscode.Disposable {
259253
if (!title || !body) {
260254
return;
261255
}
262-
await this.doCreateIssue(this.createIssueInfo.document, this.createIssueInfo.newIssue, title, body, this.createIssueInfo.assignee, this.createIssueInfo.lineNumber, this.createIssueInfo.insertIndex);
256+
await this.doCreateIssue(this.createIssueInfo?.document, this.createIssueInfo?.newIssue, title, body, this.createIssueInfo?.assignee, this.createIssueInfo?.lineNumber, this.createIssueInfo?.insertIndex);
263257
this.createIssueInfo = undefined;
264-
vscode.commands.executeCommand('workbench.action.closeActiveEditor');
258+
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
265259
}
266260

267261
async editQuery(query: vscode.TreeItem) {
@@ -431,22 +425,25 @@ export class IssueFeatureRegistrar implements vscode.Disposable {
431425
quickInput.hide();
432426
});
433427
quickInput.onDidTriggerButton(async () => {
434-
435428
title = quickInput.value;
436429
quickInput.busy = true;
437430
this.createIssueInfo = { document, newIssue, assignee, lineNumber, insertIndex };
438431

439-
const bodyPath = vscode.Uri.parse('newIssue:/NewIssue.md');
440-
const text = `${title}\n\n${body ?? ''}\n\n<!--Edit the body of your new issue then click the ✓ \"Create Issue\" button in the top right of the editor. The first line will be the issue title. Leave an empty line after the title.-->`;
441-
await vscode.workspace.fs.writeFile(bodyPath, this.stringToUint8Array(text));
442-
await vscode.window.showTextDocument(bodyPath);
432+
this.makeNewIssueFile(title, body);
443433
quickInput.busy = false;
444434
quickInput.hide();
445435
});
446436
quickInput.show();
447437
}
448438

449-
private async doCreateIssue(document: vscode.TextDocument, newIssue: NewIssue | undefined, title: string, issueBody: string | undefined, assignee: string | undefined, lineNumber: number | undefined, insertIndex: number | undefined) {
439+
private async makeNewIssueFile(title?: string, body?: string) {
440+
const bodyPath = vscode.Uri.parse(`${NEW_ISSUE_SCHEME}:/NewIssue.md`);
441+
const text = `${title ?? 'Issue Title'}\n\n${body ?? ''}\n\n<!--Edit the body of your new issue then click the ✓ \"Create Issue\" button in the top right of the editor. The first line will be the issue title. Leave an empty line after the title.-->`;
442+
await vscode.workspace.fs.writeFile(bodyPath, this.stringToUint8Array(text));
443+
await vscode.window.showTextDocument(bodyPath);
444+
}
445+
446+
private async doCreateIssue(document: vscode.TextDocument | undefined, newIssue: NewIssue | undefined, title: string, issueBody: string | undefined, assignee: string | undefined, lineNumber: number | undefined, insertIndex: number | undefined) {
450447
let origin: PullRequestDefaults | undefined;
451448
try {
452449
origin = await this.manager.getPullRequestDefaults();
@@ -464,13 +461,20 @@ export class IssueFeatureRegistrar implements vscode.Disposable {
464461
assignee
465462
});
466463
if (issue) {
467-
if ((insertIndex !== undefined) && (lineNumber !== undefined)) {
464+
if ((document !== undefined) && (insertIndex !== undefined) && (lineNumber !== undefined)) {
468465
const edit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
469466
const insertText: string = vscode.workspace.getConfiguration(ISSUES_CONFIGURATION).get('createInsertFormat', 'number') === 'number' ? `#${issue.number}` : issue.html_url;
470467
edit.insert(document.uri, new vscode.Position(lineNumber, insertIndex), ` ${insertText}`);
471468
await vscode.workspace.applyEdit(edit);
472469
} else {
473-
await vscode.env.openExternal(vscode.Uri.parse(issue.html_url));
470+
const copyIssueUrl = 'Copy URL';
471+
const openIssue = 'Open Issue';
472+
vscode.window.showInformationMessage('Issue created', copyIssueUrl, openIssue).then(async (result) => {
473+
switch (result) {
474+
case copyIssueUrl: await vscode.env.clipboard.writeText(issue.html_url); break;
475+
case openIssue: await vscode.env.openExternal(vscode.Uri.parse(issue.html_url)); break;
476+
}
477+
})
474478
}
475479
this._stateManager.refreshCacheNeeded();
476480
}

src/issues/issueFile.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ export class IssueFileSystemProvider implements vscode.FileSystemProvider {
2929
writeFile(_uri: vscode.Uri, content: Uint8Array, _options: { create: boolean; overwrite: boolean; } = { create: false, overwrite: false }): void | Thenable<void> {
3030
this.content = content;
3131
}
32-
delete(_uri: vscode.Uri, _options: { recursive: boolean; }): void | Thenable<void> { }
32+
delete(_uri: vscode.Uri, _options: { recursive: boolean; }): void | Thenable<void> {
33+
this.content = undefined;
34+
}
3335

3436
rename(_oldUri: vscode.Uri, _newUri: vscode.Uri, _options: { overwrite: boolean; }): void | Thenable<void> { }
3537
}

0 commit comments

Comments
 (0)