Browse Source

Opens files/revisions in the background

main
Eric Amodio 4 years ago
parent
commit
4c94c7922a
5 changed files with 112 additions and 108 deletions
  1. +24
    -9
      src/commands/common.ts
  2. +69
    -17
      src/commands/gitCommands.actions.ts
  3. +2
    -4
      src/commands/openChangedFiles.ts
  4. +4
    -4
      src/quickpicks/commitQuickPickItems.ts
  5. +13
    -74
      src/views/viewCommands.ts

+ 24
- 9
src/commands/common.ts View File

@ -512,12 +512,13 @@ export abstract class EditorCommand implements Disposable {
abstract execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any; abstract execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any;
} }
export function findEditor(uri: Uri, options?: { includeDiffs?: boolean }): TextEditor | undefined {
export function findEditor(uri: Uri): TextEditor | undefined {
const active = window.activeTextEditor; const active = window.activeTextEditor;
const normalizedUri = uri.toString(false);
const normalizedUri = uri.toString();
for (const e of [...(active != null ? [active] : []), ...window.visibleTextEditors]) { for (const e of [...(active != null ? [active] : []), ...window.visibleTextEditors]) {
if (e.document.uri.toString(false) === normalizedUri && (options?.includeDiffs || e?.viewColumn != null)) {
// Don't include diff editors
if (e.document.uri.toString() === normalizedUri && e?.viewColumn != null) {
return e; return e;
} }
} }
@ -527,19 +528,33 @@ export function findEditor(uri: Uri, options?: { includeDiffs?: boolean }): Text
export async function findOrOpenEditor( export async function findOrOpenEditor(
uri: Uri, uri: Uri,
openOptions?: TextDocumentShowOptions & { throwOnError?: boolean },
findOptions?: { includeDiffs?: boolean },
options?: TextDocumentShowOptions & { throwOnError?: boolean },
): Promise<TextEditor | undefined> { ): Promise<TextEditor | undefined> {
const e = findEditor(uri, findOptions);
const e = findEditor(uri);
if (e != null) { if (e != null) {
if (!openOptions?.preserveFocus) {
await window.showTextDocument(e.document, { ...openOptions, viewColumn: e.viewColumn });
if (!options?.preserveFocus) {
await window.showTextDocument(e.document, { ...options, viewColumn: e.viewColumn });
} }
return e; return e;
} }
return openEditor(uri, { viewColumn: window.activeTextEditor?.viewColumn, ...openOptions });
return openEditor(uri, { viewColumn: window.activeTextEditor?.viewColumn, ...options });
}
export function findOrOpenEditors(uris: Uri[]): void {
const normalizedUris = new Map(uris.map(uri => [uri.toString(), uri]));
for (const e of window.visibleTextEditors) {
// Don't include diff editors
if (e?.viewColumn != null) {
normalizedUris.delete(e.document.uri.toString());
}
}
for (const uri of normalizedUris.values()) {
void commands.executeCommand(BuiltInCommands.Open, uri, { background: true, preview: false });
}
} }
export async function openEditor( export async function openEditor(

+ 69
- 17
src/commands/gitCommands.actions.ts View File

@ -7,9 +7,11 @@ import {
executeCommand, executeCommand,
executeEditorCommand, executeEditorCommand,
findOrOpenEditor, findOrOpenEditor,
findOrOpenEditors,
GitCommandsCommandArgs, GitCommandsCommandArgs,
OpenWorkingFileCommandArgs, OpenWorkingFileCommandArgs,
} from '../commands'; } from '../commands';
import { FileAnnotationType } from '../configuration';
import { Container } from '../container'; import { Container } from '../container';
import { import {
GitBranchReference, GitBranchReference,
@ -24,7 +26,6 @@ import {
Repository, Repository,
} from '../git/git'; } from '../git/git';
import { GitUri } from '../git/gitUri'; import { GitUri } from '../git/gitUri';
import { FileAnnotationType } from '../configuration';
export async function executeGitCommand(args: GitCommandsCommandArgs): Promise<void> { export async function executeGitCommand(args: GitCommandsCommandArgs): Promise<void> {
void (await executeCommand<GitCommandsCommandArgs>(Commands.GitCommands, args)); void (await executeCommand<GitCommandsCommandArgs>(Commands.GitCommands, args));
@ -1025,15 +1026,30 @@ export namespace GitActions {
} }
} }
export async function openFile(uri: Uri, options?: TextDocumentShowOptions): Promise<void>;
export async function openFile( export async function openFile(
file: string | GitFile, file: string | GitFile,
ref: GitRevisionReference, ref: GitRevisionReference,
options?: TextDocumentShowOptions, options?: TextDocumentShowOptions,
): Promise<void>;
export async function openFile(
fileOrUri: string | GitFile | Uri,
refOrOptions?: GitRevisionReference | TextDocumentShowOptions,
options?: TextDocumentShowOptions,
) { ) {
let uri;
if (fileOrUri instanceof Uri) {
uri = fileOrUri;
options = refOrOptions as TextDocumentShowOptions;
} else {
const ref = refOrOptions as GitRevisionReference;
uri = GitUri.fromFile(fileOrUri, ref.repoPath, ref.ref);
}
options = { preserveFocus: true, preview: false, ...options }; options = { preserveFocus: true, preview: false, ...options };
void (await executeEditorCommand<OpenWorkingFileCommandArgs>(Commands.OpenWorkingFile, undefined, { void (await executeEditorCommand<OpenWorkingFileCommandArgs>(Commands.OpenWorkingFile, undefined, {
uri: GitUri.fromFile(file, ref.repoPath, ref.ref),
uri: uri,
showOptions: options, showOptions: options,
})); }));
} }
@ -1097,38 +1113,74 @@ export namespace GitActions {
} }
} }
export async function openFiles(commit: GitLogCommit, options?: TextDocumentShowOptions) {
if (commit.files.length > 20) {
export async function openFiles(commit: GitLogCommit): Promise<void>;
export async function openFiles(files: GitFile[], repoPath: string, ref: string): Promise<void>;
export async function openFiles(
commitOrFiles: GitLogCommit | GitFile[],
repoPath?: string,
ref?: string,
): Promise<void> {
let files;
if (GitLogCommit.is(commitOrFiles)) {
files = commitOrFiles.files;
repoPath = commitOrFiles.repoPath;
ref = commitOrFiles.sha;
} else {
files = commitOrFiles;
}
if (files.length > 20) {
const result = await window.showWarningMessage( const result = await window.showWarningMessage(
`Are your sure you want to open all ${commit.files.length} files?`,
`Are your sure you want to open all ${files.length} files?`,
{ title: 'Yes' }, { title: 'Yes' },
{ title: 'No', isCloseAffordance: true }, { title: 'No', isCloseAffordance: true },
); );
if (result == null || result.title === 'No') return; if (result == null || result.title === 'No') return;
} }
options = { preserveFocus: true, preview: false, ...options };
const uris: Uri[] = (
await Promise.all(
files.map(file => Container.git.getWorkingUri(repoPath!, GitUri.fromFile(file, repoPath!, ref))),
)
).filter(Boolean) as Uri[];
findOrOpenEditors(uris);
}
for (const file of commit.files) {
void (await openFile(file, commit, options));
export async function openFilesAtRevision(commit: GitLogCommit): Promise<void>;
export async function openFilesAtRevision(
files: GitFile[],
repoPath: string,
ref1: string,
ref2: string,
): Promise<void>;
export async function openFilesAtRevision(
commitOrFiles: GitLogCommit | GitFile[],
repoPath?: string,
ref1?: string,
ref2?: string,
): Promise<void> {
let files;
if (GitLogCommit.is(commitOrFiles)) {
files = commitOrFiles.files;
repoPath = commitOrFiles.repoPath;
ref1 = commitOrFiles.sha;
ref2 = commitOrFiles.previousFileSha;
} else {
files = commitOrFiles;
} }
}
export async function openFilesAtRevision(commit: GitLogCommit, options?: TextDocumentShowOptions) {
if (commit.files.length > 20) {
if (files.length > 20) {
const result = await window.showWarningMessage( const result = await window.showWarningMessage(
`Are your sure you want to open all ${commit.files.length} revisions?`,
`Are your sure you want to open all ${files.length} revisions?`,
{ title: 'Yes' }, { title: 'Yes' },
{ title: 'No', isCloseAffordance: true }, { title: 'No', isCloseAffordance: true },
); );
if (result == null || result.title === 'No') return; if (result == null || result.title === 'No') return;
} }
options = { preserveFocus: true, preview: false, ...options };
for (const file of commit.files) {
void (await openFileAtRevision(file, commit, options));
}
findOrOpenEditors(
files.map(file => GitUri.toRevisionUri(file.status === 'D' ? ref2! : ref1!, file, repoPath!)),
);
} }
export async function restoreFile(file: string | GitFile, ref: GitRevisionReference) { export async function restoreFile(file: string | GitFile, ref: GitRevisionReference) {

+ 2
- 4
src/commands/openChangedFiles.ts View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
import { Uri, window } from 'vscode'; import { Uri, window } from 'vscode';
import { command, Command, Commands, findOrOpenEditor, getRepoPathOrPrompt } from './common';
import { Command, command, Commands, findOrOpenEditors, getRepoPathOrPrompt } from './common';
import { Container } from '../container'; import { Container } from '../container';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { Messages } from '../messages'; import { Messages } from '../messages';
@ -34,9 +34,7 @@ export class OpenChangedFilesCommand extends Command {
args.uris = Arrays.filterMap(status.files, f => (f.status !== 'D' ? f.uri : undefined)); args.uris = Arrays.filterMap(status.files, f => (f.status !== 'D' ? f.uri : undefined));
} }
for (const uri of args.uris) {
void (await findOrOpenEditor(uri, { preserveFocus: true, preview: false }));
}
findOrOpenEditors(args.uris);
} catch (ex) { } catch (ex) {
Logger.error(ex, 'OpenChangedFilesCommand'); Logger.error(ex, 'OpenChangedFilesCommand');
void Messages.showGenericErrorMessage('Unable to open all changed files'); void Messages.showGenericErrorMessage('Unable to open all changed files');

+ 4
- 4
src/quickpicks/commitQuickPickItems.ts View File

@ -182,8 +182,8 @@ export class CommitOpenFilesCommandQuickPickItem extends CommandQuickPickItem {
super(item ?? '$(files) Open Files'); super(item ?? '$(files) Open Files');
} }
execute(options: { preserveFocus?: boolean; preview?: boolean }): Promise<void> {
return GitActions.Commit.openFiles(this.commit, options);
execute(_options: { preserveFocus?: boolean; preview?: boolean }): Promise<void> {
return GitActions.Commit.openFiles(this.commit);
} }
} }
@ -202,8 +202,8 @@ export class CommitOpenRevisionsCommandQuickPickItem extends CommandQuickPickIte
super(item ?? '$(files) Open Files at Revision'); super(item ?? '$(files) Open Files at Revision');
} }
execute(options: { preserveFocus?: boolean; preview?: boolean }): Promise<void> {
return GitActions.Commit.openFilesAtRevision(this.commit, options);
execute(_options: { preserveFocus?: boolean; preview?: boolean }): Promise<void> {
return GitActions.Commit.openFilesAtRevision(this.commit);
} }
} }

+ 13
- 74
src/views/viewCommands.ts View File

@ -7,11 +7,9 @@ import {
DiffWithWorkingCommandArgs, DiffWithWorkingCommandArgs,
executeCommand, executeCommand,
executeEditorCommand, executeEditorCommand,
findOrOpenEditor,
GitActions, GitActions,
OpenFileAtRevisionCommandArgs, OpenFileAtRevisionCommandArgs,
OpenFileOnRemoteCommandArgs, OpenFileOnRemoteCommandArgs,
OpenWorkingFileCommandArgs,
} from '../commands'; } from '../commands';
import { FileAnnotationType } from '../config'; import { FileAnnotationType } from '../config';
import { BuiltInCommands, CommandContext, setCommandContext } from '../constants'; import { BuiltInCommands, CommandContext, setCommandContext } from '../constants';
@ -748,61 +746,30 @@ export class ViewCommands {
return; return;
} }
void (await executeEditorCommand<OpenWorkingFileCommandArgs>(Commands.OpenWorkingFile, undefined, {
uri: node.uri,
showOptions: {
preserveFocus: true,
preview: false,
},
}));
await GitActions.Commit.openFile(node.uri, {
preserveFocus: true,
preview: false,
});
} }
@debug() @debug()
private async openFiles(node: CommitNode | StashNode | ResultsFilesNode, options?: TextDocumentShowOptions) {
private async openFiles(node: CommitNode | StashNode | ResultsFilesNode) {
if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) { if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) {
return; return;
} }
options = { preserveFocus: false, preview: false, ...options };
let repoPath: string;
let files;
let ref: string;
if (node instanceof ResultsFilesNode) { if (node instanceof ResultsFilesNode) {
const { diff } = await node.getFilesQueryResults(); const { diff } = await node.getFilesQueryResults();
if (diff == null || diff.length === 0) return; if (diff == null || diff.length === 0) return;
repoPath = node.repoPath;
files = diff;
ref = node.ref1 || node.ref2;
await GitActions.Commit.openFiles(diff, node.repoPath, node.ref1 || node.ref2);
} else { } else {
repoPath = node.commit.repoPath;
files = node.commit.files;
ref = node.commit.sha;
}
if (files.length > 20) {
const result = await window.showWarningMessage(
`Are your sure you want to open all ${files.length} files?`,
{ title: 'Yes' },
{ title: 'No', isCloseAffordance: true },
);
if (result === undefined || result.title === 'No') return;
}
for (const file of files) {
const uri = GitUri.fromFile(file, repoPath, ref);
await executeEditorCommand<OpenWorkingFileCommandArgs>(Commands.OpenWorkingFile, undefined, {
uri: uri,
showOptions: options,
});
await GitActions.Commit.openFiles(node.commit);
} }
} }
@debug() @debug()
private openRevision(
private async openRevision(
node: CommitFileNode | ResultsFileNode | StashFileNode | StatusFileNode, node: CommitFileNode | ResultsFileNode | StashFileNode | StatusFileNode,
options?: OpenFileAtRevisionCommandArgs, options?: OpenFileAtRevisionCommandArgs,
) { ) {
@ -812,7 +779,7 @@ export class ViewCommands {
!(node instanceof ResultsFileNode) && !(node instanceof ResultsFileNode) &&
!(node instanceof StatusFileNode) !(node instanceof StatusFileNode)
) { ) {
return undefined;
return;
} }
options = { showOptions: { preserveFocus: true, preview: false }, ...options }; options = { showOptions: { preserveFocus: true, preview: false }, ...options };
@ -833,50 +800,22 @@ export class ViewCommands {
} }
} }
return findOrOpenEditor(uri, options.showOptions ?? { preserveFocus: true, preview: false });
await GitActions.Commit.openFileAtRevision(uri, options.showOptions ?? { preserveFocus: true, preview: false });
} }
@debug() @debug()
private async openRevisions(node: CommitNode | StashNode | ResultsFilesNode, options?: TextDocumentShowOptions) {
private async openRevisions(node: CommitNode | StashNode | ResultsFilesNode, _options?: TextDocumentShowOptions) {
if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) { if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) {
return; return;
} }
options = { preserveFocus: false, preview: false, ...options };
let repoPath: string;
let files;
let ref1: string;
let ref2: string;
if (node instanceof ResultsFilesNode) { if (node instanceof ResultsFilesNode) {
const { diff } = await node.getFilesQueryResults(); const { diff } = await node.getFilesQueryResults();
if (diff == null || diff.length === 0) return; if (diff == null || diff.length === 0) return;
repoPath = node.repoPath;
files = diff;
ref1 = node.ref1;
ref2 = node.ref2;
await GitActions.Commit.openFilesAtRevision(diff, node.repoPath, node.ref1, node.ref2);
} else { } else {
repoPath = node.commit.repoPath;
files = node.commit.files;
ref1 = node.commit.sha;
ref2 = node.commit.previousFileSha;
}
if (files.length > 20) {
const result = await window.showWarningMessage(
`Are your sure you want to open all ${files.length} files?`,
{ title: 'Yes' },
{ title: 'No', isCloseAffordance: true },
);
if (result === undefined || result.title === 'No') return;
}
for (const file of files) {
const uri = GitUri.toRevisionUri(file.status === 'D' ? ref2 : ref1, file, repoPath);
await findOrOpenEditor(uri, options);
await GitActions.Commit.openFilesAtRevision(node.commit);
} }
} }

Loading…
Cancel
Save