Skip to content

Commit 9143547

Browse files
committed
Merge branch 'master' into scm-multiroot
2 parents acb83d0 + bbe70bc commit 9143547

56 files changed

Lines changed: 1458 additions & 696 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build/lib/i18n.resources.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@
154154
"name": "vs/workbench/services/editor",
155155
"project": "vscode-workbench"
156156
},
157+
{
158+
"name": "vs/workbench/services/extensions",
159+
"project": "vscode-workbench"
160+
},
157161
{
158162
"name": "vs/workbench/services/files",
159163
"project": "vscode-workbench"

extensions/emmet/npm-shrinkwrap.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/emmet/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@
212212
"@emmetio/html-matcher": "^0.3.1",
213213
"@emmetio/css-parser": "^0.4.0",
214214
"@emmetio/math-expression": "^0.1.1",
215-
"vscode-emmet-helper": "^1.0.14",
215+
"vscode-emmet-helper": "^1.0.16",
216216
"vscode-languageserver-types": "^3.0.3",
217217
"image-size": "^0.5.2",
218218
"vscode-nls": "2.0.2"

extensions/emmet/src/abbreviationActions.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function wrapWithAbbreviation(args) {
4343
const preceedingWhiteSpace = matches ? matches[1].length : 0;
4444

4545
rangeToReplace = new vscode.Range(rangeToReplace.start.line, rangeToReplace.start.character + preceedingWhiteSpace, rangeToReplace.end.line, rangeToReplace.end.character);
46-
expandAbbrList.push({ syntax, abbreviation, rangeToReplace, textToWrap: ['\n\t\$TM_SELECTED_TEXT\n'] });
46+
expandAbbrList.push({ syntax, abbreviation, rangeToReplace, textToWrap: ['\n\t$TM_SELECTED_TEXT\n'] });
4747
});
4848

4949
return expandAbbreviationInRange(editor, expandAbbrList, true);
@@ -133,8 +133,7 @@ export function expandEmmetAbbreviation(args): Thenable<boolean> {
133133
return [rangeToReplace, abbr, []];
134134
}
135135
}
136-
137-
let extractedResults = extractAbbreviation(editor.document, position);
136+
let extractedResults = extractAbbreviation(editor.document, position, false);
138137
if (!extractedResults) {
139138
return [null, '', []];
140139
}
@@ -289,10 +288,17 @@ function expandAbbr(input: ExpandAbbreviationInput): string {
289288
// Expand the abbreviation
290289
let expandedText = expandAbbreviation(input.abbreviation, expandOptions);
291290

292-
// If the expanded text is single line then we dont need the \t we added to $TM_SELECTED_TEXT earlier
293-
if (input.textToWrap && input.textToWrap.length === 1 && expandedText.indexOf('\n') === -1) {
294-
expandedText = expandedText.replace(/\s*\$TM_SELECTED_TEXT\s*/, '\$TM_SELECTED_TEXT');
291+
if (input.textToWrap) {
292+
// All $anyword would have been escaped by the emmet helper.
293+
// Remove the escaping backslash from $TM_SELECTED_TEXT so that VS Code Snippet controller can treat it as a variable
294+
expandedText = expandedText.replace('\\$TM_SELECTED_TEXT', '$TM_SELECTED_TEXT');
295+
296+
// If the expanded text is single line then we dont need the \t and \n we added to $TM_SELECTED_TEXT earlier
297+
if (input.textToWrap.length === 1 && expandedText.indexOf('\n') === -1) {
298+
expandedText = expandedText.replace(/\s*\$TM_SELECTED_TEXT\s*/, '$TM_SELECTED_TEXT');
299+
}
295300
}
301+
296302
return expandedText;
297303

298304
} catch (e) {

extensions/git/package.json

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,21 @@
251251
"command": "git.ignore",
252252
"title": "%command.ignore%",
253253
"category": "Git"
254+
},
255+
{
256+
"command": "git.stash",
257+
"title": "%command.stash%",
258+
"category": "Git"
259+
},
260+
{
261+
"command": "git.stashPop",
262+
"title": "%command.stashPop%",
263+
"category": "Git"
264+
},
265+
{
266+
"command": "git.stashPopLatest",
267+
"title": "%command.stashPopLatest%",
268+
"category": "Git"
254269
}
255270
],
256271
"menus": {
@@ -402,6 +417,18 @@
402417
{
403418
"command": "git.showOutput",
404419
"when": "config.git.enabled && scmProvider == git && gitState == idle"
420+
},
421+
{
422+
"command": "git.stash",
423+
"when": "config.git.enabled && scmProvider == git && gitState == idle"
424+
},
425+
{
426+
"command": "git.stashPop",
427+
"when": "config.git.enabled && scmProvider == git && gitState == idle"
428+
},
429+
{
430+
"command": "git.stashPopLatest",
431+
"when": "config.git.enabled && scmProvider == git && gitState == idle"
405432
}
406433
],
407434
"scm/title": [
@@ -501,7 +528,22 @@
501528
},
502529
{
503530
"command": "git.showOutput",
504-
"group": "5_output",
531+
"group": "6_output",
532+
"when": "config.git.enabled && scmProvider == git && gitState == idle"
533+
},
534+
{
535+
"command": "git.stash",
536+
"group": "5_stash",
537+
"when": "config.git.enabled && scmProvider == git && gitState == idle"
538+
},
539+
{
540+
"command": "git.stashPop",
541+
"group": "5_stash",
542+
"when": "config.git.enabled && scmProvider == git && gitState == idle"
543+
},
544+
{
545+
"command": "git.stashPopLatest",
546+
"group": "5_stash",
505547
"when": "config.git.enabled && scmProvider == git && gitState == idle"
506548
}
507549
],
@@ -729,6 +771,16 @@
729771
"type": "boolean",
730772
"description": "%config.enableCommitSigning%",
731773
"default": false
774+
},
775+
"git.discardAllScope": {
776+
"type": "string",
777+
"enum": [
778+
"all",
779+
"tracked",
780+
"prompt"
781+
],
782+
"description": "%config.discardAllScope%",
783+
"default": false
732784
}
733785
}
734786
}

extensions/git/package.nls.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
"command.publish": "Publish Branch",
3838
"command.showOutput": "Show Git Output",
3939
"command.ignore": "Add File to .gitignore",
40+
"command.stash": "Stash",
41+
"command.stashPop": "Stash Pop",
42+
"command.stashPopLatest": "Stash Pop Latest",
4043
"config.enabled": "Whether git is enabled",
4144
"config.path": "Path to the git executable",
4245
"config.autorefresh": "Whether auto refreshing is enabled",
@@ -49,5 +52,6 @@
4952
"config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository",
5053
"config.defaultCloneDirectory": "The default location where to clone a git repository",
5154
"config.enableSmartCommit": "Commit all changes when there are no staged changes.",
52-
"config.enableCommitSigning": "Enables commit signing with GPG."
55+
"config.enableCommitSigning": "Enables commit signing with GPG.",
56+
"config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run."
5357
}

extensions/git/src/commands.ts

Lines changed: 112 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -625,38 +625,90 @@ export class CommandCenter {
625625
}
626626

627627
const resources = resourceStates
628-
.filter(s => s instanceof Resource && s.resourceGroup instanceof WorkingTreeGroup)
629-
.map(r => r.resourceUri);
628+
.filter(s => s instanceof Resource && s.resourceGroup instanceof WorkingTreeGroup) as Resource[];
630629

631630
if (!resources.length) {
632631
return;
633632
}
634633

635-
const message = resources.length === 1
636-
? localize('confirm discard', "Are you sure you want to discard changes in {0}?", path.basename(resources[0].fsPath))
637-
: localize('confirm discard multiple', "Are you sure you want to discard changes in {0} files?", resources.length);
634+
const untrackedCount = resources.reduce((s, r) => s + (r.type === Status.UNTRACKED ? 1 : 0), 0);
635+
let message: string;
636+
let yes = localize('discard', "Discard Changes");
637+
638+
if (resources.length === 1) {
639+
if (untrackedCount > 0) {
640+
message = localize('confirm delete', "Are you sure you want to DELETE {0}?", path.basename(resources[0].resourceUri.fsPath));
641+
yes = localize('delete file', "Delete file");
642+
} else {
643+
message = localize('confirm discard', "Are you sure you want to discard changes in {0}?", path.basename(resources[0].resourceUri.fsPath));
644+
}
645+
} else {
646+
message = localize('confirm discard multiple', "Are you sure you want to discard changes in {0} files?", resources.length);
647+
648+
if (untrackedCount > 0) {
649+
message = `${message}\n\n${localize('warn untracked', "This will DELETE {0} untracked files!", untrackedCount)}`;
650+
}
651+
}
638652

639-
const yes = localize('discard', "Discard Changes");
640653
const pick = await window.showWarningMessage(message, { modal: true }, yes);
641654

642655
if (pick !== yes) {
643656
return;
644657
}
645658

646-
await model.clean(...resources);
659+
await model.clean(...resources.map(r => r.resourceUri));
647660
}
648661

649662
@command('git.cleanAll', { model: true })
650663
async cleanAll(model: Model): Promise<void> {
651-
const message = localize('confirm discard all', "Are you sure you want to discard ALL changes? This is IRREVERSIBLE!");
664+
const config = workspace.getConfiguration('git');
665+
let scope = config.get<string>('discardAllScope') || 'prompt';
666+
let resources = model.workingTreeGroup.resources;
667+
668+
if (resources.length === 0) {
669+
return;
670+
}
671+
672+
const untrackedCount = resources.reduce((s, r) => s + (r.type === Status.UNTRACKED ? 1 : 0), 0);
673+
674+
if (scope === 'prompt' && untrackedCount > 0) {
675+
const message = localize('there are untracked files', "There are untracked files ({0}) which will be DELETED if discarded.\n\nWould you like to delete untracked files when discarding all changes?", untrackedCount);
676+
const yes = localize('yes', "Yes");
677+
const always = localize('always', "Always");
678+
const no = localize('no', "No");
679+
const never = localize('never', "Never");
680+
const pick = await window.showWarningMessage(message, { modal: true }, yes, always, no, never);
681+
682+
if (typeof pick === 'undefined') {
683+
return;
684+
} else if (pick === always) {
685+
await config.update('discardAllScope', 'all', true);
686+
} else if (pick === never) {
687+
await config.update('discardAllScope', 'tracked', true);
688+
}
689+
690+
if (pick === never || pick === no) {
691+
scope = 'tracked';
692+
}
693+
}
694+
695+
if (scope === 'tracked') {
696+
resources = resources.filter(r => r.type !== Status.UNTRACKED && r.type !== Status.IGNORED);
697+
}
698+
699+
if (resources.length === 0) {
700+
return;
701+
}
702+
703+
const message = localize('confirm discard all', "Are you sure you want to discard ALL ({0}) changes?\nThis is IRREVERSIBLE!\nYour current working set will be FOREVER LOST.", resources.length);
652704
const yes = localize('discardAll', "Discard ALL Changes");
653705
const pick = await window.showWarningMessage(message, { modal: true }, yes);
654706

655707
if (pick !== yes) {
656708
return;
657709
}
658710

659-
await model.clean(...model.workingTreeGroup.resources.map(r => r.resourceUri));
711+
await model.clean(...resources.map(r => r.resourceUri));
660712
}
661713

662714
private async smartCommit(
@@ -1122,6 +1174,57 @@ export class CommandCenter {
11221174
await model.ignore(uris);
11231175
}
11241176

1177+
@command('git.stash', { model: true })
1178+
async stash(model: Model): Promise<void> {
1179+
if (model.workingTreeGroup.resources.length === 0) {
1180+
window.showInformationMessage(localize('no changes stash', "There are no changes to stash."));
1181+
return;
1182+
}
1183+
1184+
const message = await window.showInputBox({
1185+
prompt: localize('provide stash message', "Optionally provide a stash message"),
1186+
placeHolder: localize('stash message', "Stash message")
1187+
});
1188+
1189+
if (typeof message === 'undefined') {
1190+
return;
1191+
}
1192+
1193+
await model.createStash(message);
1194+
}
1195+
1196+
@command('git.stashPop', { model: true })
1197+
async stashPop(model: Model): Promise<void> {
1198+
const stashes = await model.getStashes();
1199+
1200+
if (stashes.length === 0) {
1201+
window.showInformationMessage(localize('no stashes', "There are no stashes to restore."));
1202+
return;
1203+
}
1204+
1205+
const picks = stashes.map(r => ({ label: `#${r.index}: ${r.description}`, description: '', details: '', id: r.index }));
1206+
const placeHolder = localize('pick stash to pop', "Pick a stash to pop");
1207+
const choice = await window.showQuickPick(picks, { placeHolder });
1208+
1209+
if (!choice) {
1210+
return;
1211+
}
1212+
1213+
await model.popStash(choice.id);
1214+
}
1215+
1216+
@command('git.stashPopLatest', { model: true })
1217+
async stashPopLatest(model: Model): Promise<void> {
1218+
const stashes = await model.getStashes();
1219+
1220+
if (stashes.length === 0) {
1221+
window.showInformationMessage(localize('no stashes', "There are no stashes to restore."));
1222+
return;
1223+
}
1224+
1225+
await model.popStash();
1226+
}
1227+
11251228
private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any {
11261229
const result = (...args) => {
11271230
// if (!skipModelCheck && !this.model) {

0 commit comments

Comments
 (0)