diff --git a/README.md b/README.md index b2a1943f..6d13f273 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,9 @@ Here are all of the extension settings with their default values. To change any // Whether auto refreshing is enabled "svn.autorefresh": true, + // Select all files when commit changes + "svn.commit.changes.selectedAll": true, + // Set file to status resolved after fix conflicts "svn.conflicts.autoResolve": null, diff --git a/package.json b/package.json index 3051adbc..266dc63e 100644 --- a/package.json +++ b/package.json @@ -1003,6 +1003,11 @@ "description": "Whether auto refreshing is enabled", "default": true }, + "svn.commit.changes.selectedAll": { + "type": "boolean", + "description": "Select all files when commit changes", + "default": true + }, "svn.conflicts.autoResolve": { "type": "boolean", "description": "Set file to status resolved after fix conflicts", diff --git a/src/changelistItems.ts b/src/changelistItems.ts index 6c09cb42..428a0c6d 100644 --- a/src/changelistItems.ts +++ b/src/changelistItems.ts @@ -5,6 +5,7 @@ import IgnoredChangeListItem from "./quickPickItems/ignoredChangeListItem"; import NewChangeListItem from "./quickPickItems/newChangeListItem"; import RemoveChangeListItem from "./quickPickItems/removeChangeListItem"; import { Repository } from "./repository"; +import { FileItem } from "./quickPickItems/fileItem"; export function getChangelistPickOptions( repository: Repository, @@ -116,6 +117,36 @@ export async function inputCommitChangelist(repository: Repository) { return choice; } +export async function inputCommitFiles(repository: Repository) { + const choice = await inputCommitChangelist(repository); + if (!choice) { + return; + } + + if ( + choice.id === "changes" && + choice.resourceGroup.resourceStates.length > 1 + ) { + const selectedAll = configuration.get("commit.changes.selectedAll", true); + + const picks = choice.resourceGroup.resourceStates.map( + r => new FileItem(repository, r, selectedAll) + ); + const selected = await window.showQuickPick(picks, { + placeHolder: "Select files to commit", + canPickMany: true + }); + + if (selected !== undefined && selected.length > 0) { + return selected.map(s => s.state); + } + + return; + } + + return choice.resourceGroup.resourceStates; +} + export function patchChangelistOptions(repository: Repository) { const picks: QuickPickItem[] = []; diff --git a/src/commands/commitWithMessage.ts b/src/commands/commitWithMessage.ts index d1d5be2a..5c2d4390 100644 --- a/src/commands/commitWithMessage.ts +++ b/src/commands/commitWithMessage.ts @@ -1,6 +1,6 @@ import * as path from "path"; import { window } from "vscode"; -import { inputCommitChangelist } from "../changelistItems"; +import { inputCommitFiles } from "../changelistItems"; import { Status } from "../common/types"; import { inputCommitMessage } from "../messages"; import { Repository } from "../repository"; @@ -13,12 +13,12 @@ export class CommitWithMessage extends Command { } public async execute(repository: Repository) { - const choice = await inputCommitChangelist(repository); - if (!choice) { + const resourceStates = await inputCommitFiles(repository); + if (!resourceStates || resourceStates.length === 0) { return; } - const filePaths = choice.resourceGroup.resourceStates.map(state => { + const filePaths = resourceStates.map(state => { return state.resourceUri.fsPath; }); @@ -32,7 +32,7 @@ export class CommitWithMessage extends Command { } // If files is renamed, the commit need previous file - choice.resourceGroup.resourceStates.forEach(state => { + resourceStates.forEach(state => { if (state instanceof Resource) { if (state.type === Status.ADDED && state.renameResourceUri) { filePaths.push(state.renameResourceUri.fsPath); diff --git a/src/quickPickItems/changeListItem.ts b/src/quickPickItems/changeListItem.ts index 6584e9d3..437b93cb 100644 --- a/src/quickPickItems/changeListItem.ts +++ b/src/quickPickItems/changeListItem.ts @@ -1,16 +1,21 @@ -import { QuickPickItem, SourceControlResourceGroup } from "vscode"; +import { QuickPickItem } from "vscode"; +import { ISvnResourceGroup } from "../common/types"; export default class ChangeListItem implements QuickPickItem { - constructor(protected group: SourceControlResourceGroup) {} + constructor(protected group: ISvnResourceGroup) {} get label(): string { return this.group.id.replace(/^changelist-/, ""); } + get id(): string { + return this.group.id; + } + get description(): string { return this.group.label; } - get resourceGroup(): SourceControlResourceGroup { + get resourceGroup(): ISvnResourceGroup { return this.group; } } diff --git a/src/quickPickItems/fileItem.ts b/src/quickPickItems/fileItem.ts new file mode 100644 index 00000000..8ab2b71a --- /dev/null +++ b/src/quickPickItems/fileItem.ts @@ -0,0 +1,24 @@ +import { QuickPickItem } from "vscode"; +import { Repository } from "../repository"; +import { Resource } from "../resource"; + +export class FileItem implements QuickPickItem { + constructor( + protected _repository: Repository, + protected _state: Resource, + public picked = false + ) {} + + get label(): string { + return this._repository.repository.removeAbsolutePath( + this._state.resourceUri.fsPath + ); + } + + get description(): string { + return this._state.resourceUri.fsPath; + } + get state(): Resource { + return this._state; + } +} diff --git a/src/test/commands.test.ts b/src/test/commands.test.ts index 98d4ff8c..caecc305 100644 --- a/src/test/commands.test.ts +++ b/src/test/commands.test.ts @@ -61,7 +61,7 @@ suite("Commands Tests", () => { assert.equal(repository.changes.resourceStates.length, 1); }); - test("Commit File", async function() { + test("Commit Single File", async function() { const repository = sourceControlManager.getRepository( checkoutDir ) as Repository; @@ -165,11 +165,33 @@ suite("Commands Tests", () => { assert.equal(repository.changes.resourceStates.length, 0); }); - test("Commit File", async function() { + test("Commit Multiple", async function() { + const file1 = path.join(checkoutDir.fsPath, "file1.txt"); + fs.writeFileSync(file1, "test"); + await commands.executeCommand("svn.openFile", Uri.file(file1)); + + const file2 = path.join(checkoutDir.fsPath, "file2.txt"); + fs.writeFileSync(file2, "test"); + await commands.executeCommand("svn.openFile", Uri.file(file2)); + const repository = sourceControlManager.getRepository( checkoutDir ) as Repository; - repository.inputBox.value = "First Commit"; + repository.inputBox.value = "Multiple Files Commit"; + + await commands.executeCommand("svn.refresh"); + await commands.executeCommand( + "svn.add", + repository.unversioned.resourceStates[0] + ); + await commands.executeCommand("svn.refresh"); + await commands.executeCommand( + "svn.add", + repository.unversioned.resourceStates[0] + ); + await commands.executeCommand("svn.refresh"); + + testUtil.overrideNextShowQuickPick(0); await commands.executeCommand("svn.commitWithMessage"); });