diff --git a/plugins/textmate/lib/bundles/docker/package.json b/plugins/textmate/lib/bundles/docker/package.json index f5f2f795fc46..c1b91dc283d5 100644 --- a/plugins/textmate/lib/bundles/docker/package.json +++ b/plugins/textmate/lib/bundles/docker/package.json @@ -12,15 +12,22 @@ "contributes": { "languages": [{ "id": "dockerfile", - "extensions": [ ".dockerfile" ], - "filenames": [ "Dockerfile" ], - "aliases": [ "Dockerfile" ], + "extensions": [ ".dockerfile", ".containerfile" ], + "filenames": [ "Dockerfile", "Containerfile" ], + "aliases": [ "Dockerfile", "Containerfile" ], "configuration": "./language-configuration.json" }], "grammars": [{ "language": "dockerfile", "scopeName": "source.dockerfile", "path": "./syntaxes/docker.tmLanguage.json" - }] + }], + "configurationDefaults": { + "[dockerfile]": { + "editor.quickSuggestions": { + "strings": true + } + } + } } -} \ No newline at end of file +} diff --git a/plugins/textmate/lib/bundles/git/package.json b/plugins/textmate/lib/bundles/git/package.json index 289aba571e95..d33bafbad5fa 100644 --- a/plugins/textmate/lib/bundles/git/package.json +++ b/plugins/textmate/lib/bundles/git/package.json @@ -105,6 +105,12 @@ "category": "Git", "icon": "$(add)" }, + { + "command": "git.stageAllMerge", + "title": "%command.stageAllMerge%", + "category": "Git", + "icon": "$(add)" + }, { "command": "git.stageSelectedRanges", "title": "%command.stageSelectedRanges%", @@ -409,6 +415,11 @@ "command": "git.timeline.copyCommitMessage", "title": "%command.timelineCopyCommitMessage%", "category": "Git" + }, + { + "command": "git.rebaseAbort", + "title": "%command.rebaseAbort%", + "category": "Git" } ], "keybindings": [ @@ -485,6 +496,10 @@ "command": "git.stageAllUntracked", "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0" }, + { + "command": "git.stageAllMerge", + "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0" + }, { "command": "git.stageSelectedRanges", "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0" @@ -609,10 +624,6 @@ "command": "git.pullRebase", "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0" }, - { - "command": "git.pullFrom", - "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0" - }, { "command": "git.merge", "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0" @@ -896,12 +907,12 @@ ], "scm/resourceGroup/context": [ { - "command": "git.stageAll", + "command": "git.stageAllMerge", "when": "scmProvider == git && scmResourceGroup == merge", "group": "1_modification" }, { - "command": "git.stageAll", + "command": "git.stageAllMerge", "when": "scmProvider == git && scmResourceGroup == merge", "group": "inline" }, @@ -1663,6 +1674,21 @@ "default": "mixed", "description": "%config.untrackedChanges%", "scope": "resource" + }, + "git.showCommitInput": { + "type": "boolean", + "scope": "resource", + "default": true, + "description": "%config.showCommitInput%" + }, + "git.terminalAuthentication": { + "type": "boolean", + "scope": "resource", + "default": true, + "description": "%config.terminalAuthentication%" + }, + "git.githubAuthentication": { + "deprecationMessage": "This setting is now deprecated, please use `github.gitAuthentication` instead." } } }, @@ -1775,6 +1801,7 @@ "ignore" ], "filenames": [ + ".gitignore_global", ".gitignore" ], "configuration": "./languages/ignore.language-configuration.json" @@ -1823,26 +1850,27 @@ { "view": "scm", "contents": "%view.workbench.scm.empty%", - "when": "config.git.enabled && !git.missing && workbenchState == empty" + "when": "config.git.enabled && git.state == initialized && workbenchState == empty" }, { "view": "scm", "contents": "%view.workbench.scm.folder%", - "when": "config.git.enabled && !git.missing && workbenchState == folder" + "when": "config.git.enabled && git.state == initialized && workbenchState == folder" }, { "view": "scm", "contents": "%view.workbench.scm.workspace%", - "when": "config.git.enabled && !git.missing && workbenchState == workspace && workspaceFolderCount != 0" + "when": "config.git.enabled && git.state == initialized && workbenchState == workspace && workspaceFolderCount != 0" }, { "view": "scm", "contents": "%view.workbench.scm.emptyWorkspace%", - "when": "config.git.enabled && !git.missing && workbenchState == workspace && workspaceFolderCount == 0" + "when": "config.git.enabled && git.state == initialized && workbenchState == workspace && workspaceFolderCount == 0" }, { "view": "explorer", - "contents": "%view.workbench.cloneRepository%" + "contents": "%view.workbench.cloneRepository%", + "when": "config.git.enabled" } ] }, diff --git a/plugins/textmate/lib/bundles/git/package.nls.json b/plugins/textmate/lib/bundles/git/package.nls.json index 40941049166f..be817e22df1e 100644 --- a/plugins/textmate/lib/bundles/git/package.nls.json +++ b/plugins/textmate/lib/bundles/git/package.nls.json @@ -14,6 +14,7 @@ "command.stageAll": "Stage All Changes", "command.stageAllTracked": "Stage All Tracked Changes", "command.stageAllUntracked": "Stage All Untracked Changes", + "command.stageAllMerge": "Stage All Merge Changes", "command.stageSelectedRanges": "Stage Selected Ranges", "command.revertSelectedRanges": "Revert Selected Ranges", "command.stageChange": "Stage Change", @@ -55,7 +56,7 @@ "command.pushToForce": "Push to... (Force)", "command.pushFollowTags": "Push (Follow Tags)", "command.pushFollowTagsForce": "Push (Follow Tags, Force)", - "command.addRemote": "Add Remote", + "command.addRemote": "Add Remote...", "command.removeRemote": "Remove Remote", "command.sync": "Sync", "command.syncRebase": "Sync (Rebase)", @@ -63,6 +64,7 @@ "command.showOutput": "Show Git Output", "command.ignore": "Add to .gitignore", "command.revealInExplorer": "Reveal in Side Bar", + "command.rebaseAbort": "Abort Rebase", "command.stashIncludeUntracked": "Stash (Include Untracked)", "command.stash": "Stash", "command.stashPop": "Pop Stash...", @@ -143,6 +145,8 @@ "config.untrackedChanges.mixed": "All changes, tracked and untracked, appear together and behave equally.", "config.untrackedChanges.separate": "Untracked changes appear separately in the Source Control view. They are also excluded from several actions.", "config.untrackedChanges.hidden": "Untracked changes are hidden and excluded from several actions.", + "config.showCommitInput": "Controls whether to show the commit input in the Git source control panel.", + "config.terminalAuthentication": "Controls whether to enable VS Code to be the authentication handler for git processes spawned in the integrated terminal. Note: terminals need to be restarted to pick up a change in this setting.", "colors.added": "Color for added resources.", "colors.modified": "Color for modified resources.", "colors.deleted": "Color for deleted resources.", diff --git a/plugins/textmate/lib/bundles/git/src/api/api1.ts b/plugins/textmate/lib/bundles/git/src/api/api1.ts index ad32607f53ba..a6d2cd4b3d39 100644 --- a/plugins/textmate/lib/bundles/git/src/api/api1.ts +++ b/plugins/textmate/lib/bundles/git/src/api/api1.ts @@ -5,7 +5,7 @@ import { Model } from '../model'; import { Repository as BaseRepository, Resource } from '../repository'; -import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, GitExtension, RefType } from './git'; +import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, GitExtension, RefType, RemoteSourceProvider, CredentialsProvider, BranchQuery } from './git'; import { Event, SourceControlInputBox, Uri, SourceControl, Disposable, commands } from 'vscode'; import { mapEvent } from '../util'; import { toGitUri } from '../uri'; @@ -159,6 +159,10 @@ export class ApiRepository implements Repository { return this._repository.getBranch(name); } + getBranches(query: BranchQuery): Promise { + return this._repository.getBranches(query); + } + setBranchUpstream(name: string, upstream: string): Promise { return this._repository.setBranchUpstream(name, upstream); } @@ -183,6 +187,10 @@ export class ApiRepository implements Repository { return this._repository.removeRemote(name); } + renameRemote(name: string, newName: string): Promise { + return this._repository.renameRemote(name, newName); + } + fetch(remote?: string | undefined, ref?: string | undefined, depth?: number | undefined): Promise { return this._repository.fetch(remote, ref, depth); } @@ -248,6 +256,21 @@ export class ApiImpl implements API { return result ? new ApiRepository(result) : null; } + async init(root: Uri): Promise { + const path = root.fsPath; + await this._model.git.init(path); + await this._model.openRepository(path); + return this.getRepository(root) || null; + } + + registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable { + return this._model.registerRemoteSourceProvider(provider); + } + + registerCredentialsProvider(provider: CredentialsProvider): Disposable { + return this._model.registerCredentialsProvider(provider); + } + constructor(private _model: Model) { } } diff --git a/plugins/textmate/lib/bundles/git/src/api/git.d.ts b/plugins/textmate/lib/bundles/git/src/api/git.d.ts index c688a4444278..7d915d01ce33 100644 --- a/plugins/textmate/lib/bundles/git/src/api/git.d.ts +++ b/plugins/textmate/lib/bundles/git/src/api/git.d.ts @@ -3,7 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Uri, SourceControlInputBox, Event, CancellationToken } from 'vscode'; +import { Uri, Event, Disposable, ProviderResult } from 'vscode'; +export { ProviderResult } from 'vscode'; export interface Git { readonly path: string; @@ -120,6 +121,7 @@ export interface RepositoryUIState { export interface LogOptions { /** Max number of log entries to retrieve. If not specified, the default is 32. */ readonly maxEntries?: number; + readonly path?: string; } export interface CommitOptions { @@ -130,6 +132,11 @@ export interface CommitOptions { empty?: boolean; } +export interface BranchQuery { + readonly remote?: boolean; + readonly contains?: string; +} + export interface Repository { readonly rootUri: Uri; @@ -169,6 +176,7 @@ export interface Repository { createBranch(name: string, checkout: boolean, ref?: string): Promise; deleteBranch(name: string, force?: boolean): Promise; getBranch(name: string): Promise; + getBranches(query: BranchQuery): Promise; setBranchUpstream(name: string, upstream: string): Promise; getMergeBase(ref1: string, ref2: string): Promise; @@ -178,6 +186,7 @@ export interface Repository { addRemote(name: string, url: string): Promise; removeRemote(name: string): Promise; + renameRemote(name: string, newName: string): Promise; fetch(remote?: string, ref?: string, depth?: number): Promise; pull(unshallow?: boolean): Promise; @@ -189,6 +198,29 @@ export interface Repository { commit(message: string, opts?: CommitOptions): Promise; } +export interface RemoteSource { + readonly name: string; + readonly description?: string; + readonly url: string | string[]; +} + +export interface RemoteSourceProvider { + readonly name: string; + readonly icon?: string; // codicon name + readonly supportsQuery?: boolean; + getRemoteSources(query?: string): ProviderResult; + publishRepository?(repository: Repository): Promise; +} + +export interface Credentials { + readonly username: string; + readonly password: string; +} + +export interface CredentialsProvider { + getCredentials(host: Uri): ProviderResult; +} + export type APIState = 'uninitialized' | 'initialized'; export interface API { @@ -201,6 +233,10 @@ export interface API { toGitUri(uri: Uri, ref: string): Uri; getRepository(uri: Uri): Repository | null; + init(root: Uri): Promise; + + registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable; + registerCredentialsProvider(provider: CredentialsProvider): Disposable; } export interface GitExtension { diff --git a/plugins/textmate/lib/bundles/git/src/askpass.sh b/plugins/textmate/lib/bundles/git/src/askpass.sh index b6d374f2c38e..d19b62affa3a 100755 --- a/plugins/textmate/lib/bundles/git/src/askpass.sh +++ b/plugins/textmate/lib/bundles/git/src/askpass.sh @@ -1,5 +1,5 @@ #!/bin/sh VSCODE_GIT_ASKPASS_PIPE=`mktemp` -VSCODE_GIT_ASKPASS_PIPE="$VSCODE_GIT_ASKPASS_PIPE" "$VSCODE_GIT_ASKPASS_NODE" "$VSCODE_GIT_ASKPASS_MAIN" $* +ELECTRON_RUN_AS_NODE="1" VSCODE_GIT_ASKPASS_PIPE="$VSCODE_GIT_ASKPASS_PIPE" "$VSCODE_GIT_ASKPASS_NODE" "$VSCODE_GIT_ASKPASS_MAIN" $* cat $VSCODE_GIT_ASKPASS_PIPE -rm $VSCODE_GIT_ASKPASS_PIPE \ No newline at end of file +rm $VSCODE_GIT_ASKPASS_PIPE diff --git a/plugins/textmate/lib/bundles/git/src/askpass.ts b/plugins/textmate/lib/bundles/git/src/askpass.ts index dd7e84c2e030..7fc29a371ad9 100644 --- a/plugins/textmate/lib/bundles/git/src/askpass.ts +++ b/plugins/textmate/lib/bundles/git/src/askpass.ts @@ -3,36 +3,67 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { window, InputBoxOptions } from 'vscode'; -import { IDisposable } from './util'; +import { window, InputBoxOptions, Uri, OutputChannel, Disposable, workspace } from 'vscode'; +import { IDisposable, EmptyDisposable, toDisposable } from './util'; import * as path from 'path'; -import { IIPCHandler, IIPCServer } from './ipc/ipcServer'; - -export interface AskpassEnvironment { - GIT_ASKPASS: string; - ELECTRON_RUN_AS_NODE?: string; - VSCODE_GIT_ASKPASS_NODE?: string; - VSCODE_GIT_ASKPASS_MAIN?: string; - VSCODE_GIT_ASKPASS_HANDLE?: string; -} +import { IIPCHandler, IIPCServer, createIPCServer } from './ipc/ipcServer'; +import { CredentialsProvider, Credentials } from './api/git'; export class Askpass implements IIPCHandler { - private disposable: IDisposable; + private disposable: IDisposable = EmptyDisposable; + private cache = new Map(); + private credentialsProviders = new Set(); - static getDisabledEnv(): AskpassEnvironment { - return { - GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh') - }; + static async create(outputChannel: OutputChannel, context?: string): Promise { + try { + return new Askpass(await createIPCServer(context)); + } catch (err) { + outputChannel.appendLine(`[error] Failed to create git askpass IPC: ${err}`); + return new Askpass(); + } } - constructor(ipc: IIPCServer) { - this.disposable = ipc.registerHandler('askpass', this); + private constructor(private ipc?: IIPCServer) { + if (ipc) { + this.disposable = ipc.registerHandler('askpass', this); + } } async handle({ request, host }: { request: string, host: string }): Promise { + const config = workspace.getConfiguration('git', null); + const enabled = config.get('enabled'); + + if (!enabled) { + return ''; + } + + const uri = Uri.parse(host); + const authority = uri.authority.replace(/^.*@/, ''); + const password = /password/i.test(request); + const cached = this.cache.get(authority); + + if (cached && password) { + this.cache.delete(authority); + return cached.password; + } + + if (!password) { + for (const credentialsProvider of this.credentialsProviders) { + try { + const credentials = await credentialsProvider.getCredentials(uri); + + if (credentials) { + this.cache.set(authority, credentials); + setTimeout(() => this.cache.delete(authority), 60_000); + return credentials.username; + } + } catch { } + } + } + const options: InputBoxOptions = { - password: /password/i.test(request), + password, placeHolder: request, prompt: `Git: ${host}`, ignoreFocusOut: true @@ -41,15 +72,26 @@ export class Askpass implements IIPCHandler { return await window.showInputBox(options) || ''; } - getEnv(): AskpassEnvironment { + getEnv(): { [key: string]: string; } { + if (!this.ipc) { + return { + GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh') + }; + } + return { - ELECTRON_RUN_AS_NODE: '1', + ...this.ipc.getEnv(), GIT_ASKPASS: path.join(__dirname, 'askpass.sh'), VSCODE_GIT_ASKPASS_NODE: process.execPath, VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js') }; } + registerCredentialsProvider(provider: CredentialsProvider): Disposable { + this.credentialsProviders.add(provider); + return toDisposable(() => this.credentialsProviders.delete(provider)); + } + dispose(): void { this.disposable.dispose(); } diff --git a/plugins/textmate/lib/bundles/git/src/commands.ts b/plugins/textmate/lib/bundles/git/src/commands.ts index e8a696735fc4..e60dc39e6a64 100644 --- a/plugins/textmate/lib/bundles/git/src/commands.ts +++ b/plugins/textmate/lib/bundles/git/src/commands.ts @@ -6,10 +6,10 @@ import { lstat, Stats } from 'fs'; import * as os from 'os'; import * as path from 'path'; -import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env } from 'vscode'; +import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, QuickPick } from 'vscode'; import TelemetryReporter from 'vscode-extension-telemetry'; import * as nls from 'vscode-nls'; -import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions } from './api/git'; +import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourceProvider, RemoteSource } from './api/git'; import { ForcePushMode, Git, Stash } from './git'; import { Model } from './model'; import { Repository, Resource, ResourceGroupType } from './repository'; @@ -18,6 +18,8 @@ import { fromGitUri, toGitUri, isGitUri } from './uri'; import { grep, isDescendant, pathEquals } from './util'; import { Log, LogLevel } from './log'; import { GitTimelineItem } from './timelineProvider'; +import { throttle, debounce } from './decorators'; +import { ApiRepository } from './api/api1'; const localize = nls.loadMessageBundle(); @@ -215,6 +217,11 @@ function createCheckoutItems(repository: Repository): CheckoutItem[] { return [...heads, ...tags, ...remoteHeads]; } +function sanitizeRemoteName(name: string) { + name = name.trim(); + return name && name.replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, '-'); +} + class TagItem implements QuickPickItem { get label(): string { return this.ref.name ?? ''; } get description(): string { return this.ref.commit?.substr(0, 8) ?? ''; } @@ -233,6 +240,72 @@ interface PushOptions { silent?: boolean; } +async function getQuickPickResult(quickpick: QuickPick): Promise { + const result = await new Promise(c => { + quickpick.onDidAccept(() => c(quickpick.selectedItems[0])); + quickpick.onDidHide(() => c(undefined)); + quickpick.show(); + }); + + quickpick.hide(); + return result; +} + +class RemoteSourceProviderQuickPick { + + private quickpick: QuickPick; + + constructor(private provider: RemoteSourceProvider) { + this.quickpick = window.createQuickPick(); + this.quickpick.ignoreFocusOut = true; + + if (provider.supportsQuery) { + this.quickpick.placeholder = localize('type to search', "Repository name (type to search)"); + this.quickpick.onDidChangeValue(this.onDidChangeValue, this); + } else { + this.quickpick.placeholder = localize('type to filter', "Repository name"); + } + } + + @debounce(300) + onDidChangeValue(): void { + this.query(); + } + + @throttle + async query(): Promise { + this.quickpick.busy = true; + + try { + const remoteSources = await this.provider.getRemoteSources(this.quickpick.value) || []; + + if (remoteSources.length === 0) { + this.quickpick.items = [{ + label: localize('none found', "No remote repositories found."), + alwaysShow: true + }]; + } else { + this.quickpick.items = remoteSources.map(remoteSource => ({ + label: remoteSource.name, + description: remoteSource.description || (typeof remoteSource.url === 'string' ? remoteSource.url : remoteSource.url[0]), + remoteSource + })); + } + } catch (err) { + this.quickpick.items = [{ label: localize('error', "$(error) Error: {0}", err.message), alwaysShow: true }]; + console.error(err); + } finally { + this.quickpick.busy = false; + } + } + + async pick(): Promise { + this.query(); + const result = await getQuickPickResult(this.quickpick); + return result?.remoteSource; + } +} + export class CommandCenter { private disposables: Disposable[]; @@ -454,10 +527,51 @@ export class CommandCenter { @command('git.clone') async clone(url?: string, parentPath?: string): Promise { if (!url) { - url = await window.showInputBox({ - prompt: localize('repourl', "Repository URL"), - ignoreFocusOut: true - }); + const quickpick = window.createQuickPick<(QuickPickItem & { provider?: RemoteSourceProvider, url?: string })>(); + quickpick.ignoreFocusOut = true; + + const providers = this.model.getRemoteProviders() + .map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + localize('clonefrom', "Clone from {0}", provider.name), alwaysShow: true, provider })); + + quickpick.placeholder = providers.length === 0 + ? localize('provide url', "Provide repository URL") + : localize('provide url or pick', "Provide repository URL or pick a repository source."); + + const updatePicks = (value?: string) => { + if (value) { + quickpick.items = [{ + label: localize('repourl', "Clone from URL"), + description: value, + alwaysShow: true, + url: value + }, + ...providers]; + } else { + quickpick.items = providers; + } + }; + + quickpick.onDidChangeValue(updatePicks); + updatePicks(); + + const result = await getQuickPickResult(quickpick); + + if (result) { + if (result.url) { + url = result.url; + } else if (result.provider) { + const quickpick = new RemoteSourceProviderQuickPick(result.provider); + const remote = await quickpick.pick(); + + if (remote) { + if (typeof remote.url === 'string') { + url = remote.url; + } else if (remote.url.length > 0) { + url = await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: localize('pick url', "Choose a URL to clone from.") }); + } + } + } + } } if (!url) { @@ -886,37 +1000,14 @@ export class CommandCenter { @command('git.stageAll', { repository: true }) async stageAll(repository: Repository): Promise { - const resources = repository.mergeGroup.resourceStates.filter(s => s instanceof Resource) as Resource[]; - const { merge, unresolved, deletionConflicts } = await categorizeResourceByResolution(resources); + const resources = [...repository.workingTreeGroup.resourceStates, ...repository.untrackedGroup.resourceStates]; + const uris = resources.map(r => r.resourceUri); - try { - for (const deletionConflict of deletionConflicts) { - await this._stageDeletionConflict(repository, deletionConflict.resourceUri); - } - } catch (err) { - if (/Cancelled/.test(err.message)) { - return; - } - - throw err; + if (uris.length > 0) { + const config = workspace.getConfiguration('git', Uri.file(repository.root)); + const untrackedChanges = config.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges'); + await repository.add(uris, untrackedChanges === 'mixed' ? undefined : { update: true }); } - - if (unresolved.length > 0) { - const message = unresolved.length > 1 - ? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", merge.length) - : localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(merge[0].resourceUri.fsPath)); - - const yes = localize('yes', "Yes"); - const pick = await window.showWarningMessage(message, { modal: true }, yes); - - if (pick !== yes) { - return; - } - } - - const config = workspace.getConfiguration('git', Uri.file(repository.root)); - const untrackedChanges = config.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges'); - await repository.add([], untrackedChanges === 'mixed' ? undefined : { update: true }); } private async _stageDeletionConflict(repository: Repository, uri: Uri): Promise { @@ -972,6 +1063,43 @@ export class CommandCenter { await repository.add(uris); } + @command('git.stageAllMerge', { repository: true }) + async stageAllMerge(repository: Repository): Promise { + const resources = repository.mergeGroup.resourceStates.filter(s => s instanceof Resource) as Resource[]; + const { merge, unresolved, deletionConflicts } = await categorizeResourceByResolution(resources); + + try { + for (const deletionConflict of deletionConflicts) { + await this._stageDeletionConflict(repository, deletionConflict.resourceUri); + } + } catch (err) { + if (/Cancelled/.test(err.message)) { + return; + } + + throw err; + } + + if (unresolved.length > 0) { + const message = unresolved.length > 1 + ? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", merge.length) + : localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(merge[0].resourceUri.fsPath)); + + const yes = localize('yes', "Yes"); + const pick = await window.showWarningMessage(message, { modal: true }, yes); + + if (pick !== yes) { + return; + } + } + + const uris = resources.map(r => r.resourceUri); + + if (uris.length > 0) { + await repository.add(uris); + } + } + @command('git.stageChange') async stageChange(uri: Uri, changes: LineChange[], index: number): Promise { const textEditor = window.visibleTextEditors.filter(e => e.document.uri.toString() === uri.toString())[0]; @@ -1891,9 +2019,17 @@ export class CommandCenter { const remotes = repository.remotes; if (remotes.length === 0) { - if (!pushOptions.silent) { - window.showWarningMessage(localize('no remotes to push', "Your repository has no remotes configured to push to.")); + if (pushOptions.silent) { + return; } + + const addRemote = localize('addremote', 'Add Remote'); + const result = await window.showWarningMessage(localize('no remotes to push', "Your repository has no remotes configured to push to."), addRemote); + + if (result === addRemote) { + await this.addRemote(repository); + } + return; } @@ -2010,48 +2146,79 @@ export class CommandCenter { @command('git.addRemote', { repository: true }) async addRemote(repository: Repository): Promise { - const remotes = repository.remotes; + const quickpick = window.createQuickPick<(QuickPickItem & { provider?: RemoteSourceProvider, url?: string })>(); + quickpick.ignoreFocusOut = true; - const sanitize = (name: string) => { - name = name.trim(); - return name && name.replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, '-'); + const providers = this.model.getRemoteProviders() + .map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + localize('addfrom', "Add remote from {0}", provider.name), alwaysShow: true, provider })); + + quickpick.placeholder = providers.length === 0 + ? localize('provide url', "Provide repository URL") + : localize('provide url or pick', "Provide repository URL or pick a repository source."); + + const updatePicks = (value?: string) => { + if (value) { + quickpick.items = [{ + label: localize('addFrom', "Add remote from URL"), + description: value, + alwaysShow: true, + url: value + }, + ...providers]; + } else { + quickpick.items = providers; + } }; + quickpick.onDidChangeValue(updatePicks); + updatePicks(); + + const result = await getQuickPickResult(quickpick); + let url: string | undefined; + + if (result) { + if (result.url) { + url = result.url; + } else if (result.provider) { + const quickpick = new RemoteSourceProviderQuickPick(result.provider); + const remote = await quickpick.pick(); + + if (remote) { + if (typeof remote.url === 'string') { + url = remote.url; + } else if (remote.url.length > 0) { + url = await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: localize('pick url', "Choose a URL to clone from.") }); + } + } + } + } + + if (!url) { + return; + } + const resultName = await window.showInputBox({ placeHolder: localize('remote name', "Remote name"), prompt: localize('provide remote name', "Please provide a remote name"), ignoreFocusOut: true, validateInput: (name: string) => { - if (sanitize(name)) { - return null; + if (!sanitizeRemoteName(name)) { + return localize('remote name format invalid', "Remote name format invalid"); + } else if (repository.remotes.find(r => r.name === name)) { + return localize('remote already exists', "Remote '{0}' already exists.", name); } - return localize('remote name format invalid', "Remote name format invalid"); + + return null; } }); - const name = sanitize(resultName || ''); + const name = sanitizeRemoteName(resultName || ''); if (!name) { return; } - if (remotes.find(r => r.name === name)) { - window.showErrorMessage(localize('remote already exists', "Remote '{0}' already exists.", name)); - return; - } - - const url = await window.showInputBox({ - placeHolder: localize('remote url', "Remote URL"), - prompt: localize('provide remote URL', "Enter URL for remote \"{0}\"", name), - ignoreFocusOut: true - }); - - if (!url) { - return; - } - await repository.addRemote(name, url); - return name; } @@ -2161,15 +2328,38 @@ export class CommandCenter { @command('git.publish', { repository: true }) async publish(repository: Repository): Promise { + const branchName = repository.HEAD && repository.HEAD.name || ''; const remotes = repository.remotes; if (remotes.length === 0) { - window.showWarningMessage(localize('no remotes to publish', "Your repository has no remotes configured to publish to.")); + const providers = this.model.getRemoteProviders().filter(p => !!p.publishRepository); + + if (providers.length === 0) { + window.showWarningMessage(localize('no remotes to publish', "Your repository has no remotes configured to publish to.")); + return; + } + + let provider: RemoteSourceProvider; + + if (providers.length === 1) { + provider = providers[0]; + } else { + const picks = providers + .map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + localize('publish to', "Publish to {0}", provider.name), alwaysShow: true, provider })); + const placeHolder = localize('pick provider', "Pick a provider to publish the branch '{0}' to:", branchName); + const choice = await window.showQuickPick(picks, { placeHolder }); + + if (!choice) { + return; + } + + provider = choice.provider; + } + + await provider.publishRepository!(new ApiRepository(repository)); return; } - const branchName = repository.HEAD && repository.HEAD.name || ''; - if (remotes.length === 1) { return await repository.pushTo(remotes[0].name, branchName, true); } @@ -2387,6 +2577,10 @@ export class CommandCenter { env.clipboard.writeText(item.message); } + @command('git.rebaseAbort', { repository: true }) + async rebaseAbort(repository: Repository): Promise { + await repository.rebaseAbort(); + } private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any { const result = (...args: any[]) => { @@ -2453,6 +2647,14 @@ export class CommandCenter { type = 'warning'; options.modal = false; break; + case GitErrorCodes.AuthenticationFailed: + const regex = /Authentication failed for '(.*)'/i; + const match = regex.exec(err.stderr || String(err)); + + message = match + ? localize('auth failed specific', "Failed to authenticate to git remote:\n\n{0}", match[1]) + : localize('auth failed', "Failed to authenticate to git remote."); + break; case GitErrorCodes.NoUserNameConfigured: case GitErrorCodes.NoUserEmailConfigured: message = localize('missing user info', "Make sure you configure your 'user.name' and 'user.email' in git."); diff --git a/plugins/textmate/lib/bundles/git/src/git.ts b/plugins/textmate/lib/bundles/git/src/git.ts index 8ae6053734e8..66d91da4d7a0 100644 --- a/plugins/textmate/lib/bundles/git/src/git.ts +++ b/plugins/textmate/lib/bundles/git/src/git.ts @@ -15,7 +15,7 @@ import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes, import { CancellationToken, Progress, Uri } from 'vscode'; import { URI } from 'vscode-uri'; import { detectEncoding } from './encoding'; -import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status, CommitOptions } from './api/git'; +import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status, CommitOptions, BranchQuery } from './api/git'; import * as byline from 'byline'; import { StringDecoder } from 'string_decoder'; @@ -306,7 +306,7 @@ export interface IGitOptions { function getGitErrorCode(stderr: string): string | undefined { if (/Another git process seems to be running in this repository|If no other git process is currently running/.test(stderr)) { return GitErrorCodes.RepositoryIsLocked; - } else if (/Authentication failed/.test(stderr)) { + } else if (/Authentication failed/i.test(stderr)) { return GitErrorCodes.AuthenticationFailed; } else if (/Not a git repository/i.test(stderr)) { return GitErrorCodes.NotAGitRepository; @@ -435,14 +435,13 @@ export class Git { const [, letter] = match; try { - let networkPath = await new Promise(resolve => + const networkPath = await new Promise(resolve => realpath.native(`${letter}:`, { encoding: 'utf8' }, (err, resolvedPath) => // eslint-disable-next-line eqeqeq resolve(err != null ? undefined : resolvedPath), ), ); if (networkPath !== undefined) { - networkPath = `${networkPath}\\`; return path.normalize( repoUri.fsPath.replace( networkPath, @@ -541,7 +540,8 @@ export class Git { options.env = assign({}, process.env, this.env, options.env || {}, { VSCODE_GIT_COMMAND: args[0], LC_ALL: 'en_US.UTF-8', - LANG: 'en_US.UTF-8' + LANG: 'en_US.UTF-8', + GIT_PAGER: 'cat' }); if (options.cwd) { @@ -848,6 +848,9 @@ export class Repository { async log(options?: LogOptions): Promise { const maxEntries = options?.maxEntries ?? 32; const args = ['log', `-n${maxEntries}`, `--format=${COMMIT_FORMAT}`, '-z', '--']; + if (options?.path) { + args.push(options.path); + } const result = await this.run(args); if (result.exitCode) { @@ -1220,15 +1223,13 @@ export class Repository { args.push('-A'); } - args.push('--'); - if (paths && paths.length) { - args.push.apply(args, paths.map(sanitizePath)); + for (const chunk of splitInChunks(paths, MAX_CLI_LENGTH)) { + await this.run([...args, '--', ...chunk]); + } } else { - args.push('.'); + await this.run([...args, '--', '.']); } - - await this.run(args); } async rm(paths: string[]): Promise { @@ -1333,6 +1334,10 @@ export class Repository { } } + async rebaseAbort(): Promise { + await this.run(['rebase', '--abort']); + } + async rebaseContinue(): Promise { const args = ['rebase', '--continue']; @@ -1433,10 +1438,11 @@ export class Repository { const limiter = new Limiter(5); const promises: Promise[] = []; + const args = ['clean', '-f', '-q']; for (const paths of groups) { for (const chunk of splitInChunks(paths, MAX_CLI_LENGTH)) { - promises.push(limiter.queue(() => this.run(['clean', '-f', '-q', '--', ...chunk]))); + promises.push(limiter.queue(() => this.run([...args, '--', ...chunk]))); } } @@ -1468,19 +1474,19 @@ export class Repository { // In case there are no branches, we must use rm --cached if (!result.stdout) { - args = ['rm', '--cached', '-r', '--']; + args = ['rm', '--cached', '-r']; } else { - args = ['reset', '-q', treeish, '--']; - } - - if (paths && paths.length) { - args.push.apply(args, paths.map(sanitizePath)); - } else { - args.push('.'); + args = ['reset', '-q', treeish]; } try { - await this.run(args); + if (paths && paths.length > 0) { + for (const chunk of splitInChunks(paths, MAX_CLI_LENGTH)) { + await this.run([...args, '--', ...chunk]); + } + } else { + await this.run([...args, '--', '.']); + } } catch (err) { // In case there are merge conflicts to be resolved, git reset will output // some "needs merge" data. We try to get around that. @@ -1498,7 +1504,12 @@ export class Repository { } async removeRemote(name: string): Promise { - const args = ['remote', 'rm', name]; + const args = ['remote', 'remove', name]; + await this.run(args); + } + + async renameRemote(name: string, newName: string): Promise { + const args = ['remote', 'rename', name, newName]; await this.run(args); } @@ -1780,13 +1791,17 @@ export class Repository { .map(([ref]) => ({ name: ref, type: RefType.Head } as Branch)); } - async getRefs(opts?: { sort?: 'alphabetically' | 'committerdate' }): Promise { + async getRefs(opts?: { sort?: 'alphabetically' | 'committerdate', contains?: string }): Promise { const args = ['for-each-ref', '--format', '%(refname) %(objectname)']; if (opts && opts.sort && opts.sort !== 'alphabetically') { args.push('--sort', `-${opts.sort}`); } + if (opts?.contains) { + args.push('--contains', opts.contains); + } + const result = await this.run(args); const fn = (line: string): Ref | null => { @@ -1904,6 +1919,11 @@ export class Repository { } } + async getBranches(query: BranchQuery): Promise { + const refs = await this.getRefs({ contains: query.contains }); + return refs.filter(value => (value.type !== RefType.Tag) && (query.remote || !value.remote)); + } + // TODO: Support core.commentChar stripCommitMessageComments(message: string): string { return message.replace(/^\s*#.*$\n?/gm, '').trim(); @@ -1954,10 +1974,10 @@ export class Repository { } async updateSubmodules(paths: string[]): Promise { - const args = ['submodule', 'update', '--']; + const args = ['submodule', 'update']; for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) { - await this.run([...args, ...chunk]); + await this.run([...args, '--', ...chunk]); } } diff --git a/plugins/textmate/lib/bundles/git/src/ipc/ipcServer.ts b/plugins/textmate/lib/bundles/git/src/ipc/ipcServer.ts index 332490896cc8..5cea9faf98fd 100644 --- a/plugins/textmate/lib/bundles/git/src/ipc/ipcServer.ts +++ b/plugins/textmate/lib/bundles/git/src/ipc/ipcServer.ts @@ -11,27 +11,42 @@ import * as os from 'os'; import * as fs from 'fs'; import * as crypto from 'crypto'; -function getIPCHandlePath(nonce: string): string { +function getIPCHandlePath(id: string): string { if (process.platform === 'win32') { - return `\\\\.\\pipe\\vscode-git-ipc-${nonce}-sock`; + return `\\\\.\\pipe\\vscode-git-${id}-sock`; } if (process.env['XDG_RUNTIME_DIR']) { - return path.join(process.env['XDG_RUNTIME_DIR'] as string, `vscode-git-ipc-${nonce}.sock`); + return path.join(process.env['XDG_RUNTIME_DIR'] as string, `vscode-git-${id}.sock`); } - return path.join(os.tmpdir(), `vscode-git-ipc-${nonce}.sock`); + return path.join(os.tmpdir(), `vscode-git-${id}.sock`); } export interface IIPCHandler { handle(request: any): Promise; } -export async function createIPCServer(): Promise { +export async function createIPCServer(context?: string): Promise { const server = http.createServer(); - const buffer = await new Promise((c, e) => crypto.randomBytes(20, (err, buf) => err ? e(err) : c(buf))); - const nonce = buffer.toString('hex'); - const ipcHandlePath = getIPCHandlePath(nonce); + const hash = crypto.createHash('sha1'); + + if (!context) { + const buffer = await new Promise((c, e) => crypto.randomBytes(20, (err, buf) => err ? e(err) : c(buf))); + hash.update(buffer); + } else { + hash.update(context); + } + + const ipcHandlePath = getIPCHandlePath(hash.digest('hex').substr(0, 10)); + + if (process.platform !== 'win32') { + try { + await fs.promises.unlink(ipcHandlePath); + } catch { + // noop + } + } return new Promise((c, e) => { try { @@ -46,7 +61,7 @@ export async function createIPCServer(): Promise { export interface IIPCServer extends Disposable { readonly ipcHandlePath: string | undefined; - getEnv(): any; + getEnv(): { [key: string]: string; }; registerHandler(name: string, handler: IIPCHandler): Disposable; } @@ -91,7 +106,7 @@ class IPCServer implements IIPCServer, Disposable { }); } - getEnv(): any { + getEnv(): { [key: string]: string; } { return { VSCODE_GIT_IPC_HANDLE: this.ipcHandlePath }; } diff --git a/plugins/textmate/lib/bundles/git/src/main.ts b/plugins/textmate/lib/bundles/git/src/main.ts index 2bd8095d4182..5210aaa70f0f 100644 --- a/plugins/textmate/lib/bundles/git/src/main.ts +++ b/plugins/textmate/lib/bundles/git/src/main.ts @@ -10,7 +10,6 @@ import { ExtensionContext, workspace, window, Disposable, commands, Uri, OutputC import { findGit, Git, IGit } from './git'; import { Model } from './model'; import { CommandCenter } from './commands'; -import { GitContentProvider } from './contentProvider'; import { GitFileSystemProvider } from './fileSystemProvider'; import { GitDecorations } from './decorationProvider'; import { Askpass } from './askpass'; @@ -21,9 +20,9 @@ import { GitProtocolHandler } from './protocolHandler'; import { GitExtensionImpl } from './api/extension'; import * as path from 'path'; import * as fs from 'fs'; -import { createIPCServer, IIPCServer } from './ipc/ipcServer'; import { GitTimelineProvider } from './timelineProvider'; import { registerAPICommands } from './api/api1'; +import { TerminalEnvironmentManager } from './terminal'; const deactivateTasks: { (): Promise; }[] = []; @@ -37,27 +36,15 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann const pathHint = workspace.getConfiguration('git').get('path'); const info = await findGit(pathHint, path => outputChannel.appendLine(localize('looking', "Looking for git in: {0}", path))); - let env: any = {}; - let ipc: IIPCServer | undefined; + const askpass = await Askpass.create(outputChannel, context.storagePath); + disposables.push(askpass); - try { - ipc = await createIPCServer(); - disposables.push(ipc); - env = { ...env, ...ipc.getEnv() }; - } catch { - // noop - } - - if (ipc) { - const askpass = new Askpass(ipc); - disposables.push(askpass); - env = { ...env, ...askpass.getEnv() }; - } else { - env = { ...env, ...Askpass.getDisabledEnv() }; - } + const env = askpass.getEnv(); + const terminalEnvironmentManager = new TerminalEnvironmentManager(context, env); + disposables.push(terminalEnvironmentManager); const git = new Git({ gitPath: info.path, version: info.version, env }); - const model = new Model(git, context.globalState, outputChannel); + const model = new Model(git, askpass, context.globalState, outputChannel); disposables.push(model); const onRepository = () => commands.executeCommand('setContext', 'gitOpenRepositoryCount', `${model.repositories.length}`); @@ -81,7 +68,6 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann disposables.push( new CommandCenter(git, model, outputChannel, telemetryReporter), - new GitContentProvider(model), new GitFileSystemProvider(model), new GitDecorations(model), new GitProtocolHandler(), diff --git a/plugins/textmate/lib/bundles/git/src/model.ts b/plugins/textmate/lib/bundles/git/src/model.ts index bb6642351038..8dfbef4d506c 100644 --- a/plugins/textmate/lib/bundles/git/src/model.ts +++ b/plugins/textmate/lib/bundles/git/src/model.ts @@ -3,16 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel } from 'vscode'; +import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel, commands } from 'vscode'; import { Repository, RepositoryState } from './repository'; import { memoize, sequentialize, debounce } from './decorators'; -import { dispose, anyEvent, filterEvent, isDescendant, firstIndex, pathEquals } from './util'; +import { dispose, anyEvent, filterEvent, isDescendant, firstIndex, pathEquals, toDisposable } from './util'; import { Git } from './git'; import * as path from 'path'; import * as fs from 'fs'; import * as nls from 'vscode-nls'; import { fromGitUri } from './uri'; -import { GitErrorCodes, APIState as State } from './api/git'; +import { APIState as State, RemoteSourceProvider, CredentialsProvider } from './api/git'; +import { Askpass } from './askpass'; +import { IRemoteSourceProviderRegistry } from './remoteProvider'; const localize = nls.loadMessageBundle(); @@ -44,7 +46,7 @@ interface OpenRepository extends Disposable { repository: Repository; } -export class Model { +export class Model implements IRemoteSourceProviderRegistry { private _onDidOpenRepository = new EventEmitter(); readonly onDidOpenRepository: Event = this._onDidOpenRepository.event; @@ -72,11 +74,20 @@ export class Model { setState(state: State): void { this._state = state; this._onDidChangeState.fire(state); + commands.executeCommand('setContext', 'git.state', state); } + private remoteSourceProviders = new Set(); + + private _onDidAddRemoteSourceProvider = new EventEmitter(); + readonly onDidAddRemoteSourceProvider = this._onDidAddRemoteSourceProvider.event; + + private _onDidRemoveRemoteSourceProvider = new EventEmitter(); + readonly onDidRemoveRemoteSourceProvider = this._onDidRemoveRemoteSourceProvider.event; + private disposables: Disposable[] = []; - constructor(readonly git: Git, private globalState: Memento, private outputChannel: OutputChannel) { + constructor(readonly git: Git, private readonly askpass: Askpass, private globalState: Memento, private outputChannel: OutputChannel) { workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables); window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables); workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables); @@ -89,6 +100,7 @@ export class Model { const onPossibleGitRepositoryChange = filterEvent(onGitRepositoryChange, uri => !this.getRepository(uri)); onPossibleGitRepositoryChange(this.onPossibleGitRepositoryChange, this, this.disposables); + this.setState('uninitialized'); this.doInitialScan().finally(() => this.setState('initialized')); } @@ -112,34 +124,37 @@ export class Model { return; } - for (const folder of workspace.workspaceFolders || []) { + await Promise.all((workspace.workspaceFolders || []).map(async folder => { const root = folder.uri.fsPath; + const children = await new Promise((c, e) => fs.readdir(root, (err, r) => err ? e(err) : c(r))); + const promises = children + .filter(child => child !== '.git') + .map(child => this.openRepository(path.join(root, child))); - try { - const children = await new Promise((c, e) => fs.readdir(root, (err, r) => err ? e(err) : c(r))); + const folderConfig = workspace.getConfiguration('git', folder.uri); + const paths = folderConfig.get('scanRepositories') || []; - children - .filter(child => child !== '.git') - .forEach(child => this.openRepository(path.join(root, child))); - - const folderConfig = workspace.getConfiguration('git', folder.uri); - const paths = folderConfig.get('scanRepositories') || []; - - for (const possibleRepositoryPath of paths) { - if (path.isAbsolute(possibleRepositoryPath)) { - console.warn(localize('not supported', "Absolute paths not supported in 'git.scanRepositories' setting.")); - continue; - } - - this.openRepository(path.join(root, possibleRepositoryPath)); + for (const possibleRepositoryPath of paths) { + if (path.isAbsolute(possibleRepositoryPath)) { + console.warn(localize('not supported', "Absolute paths not supported in 'git.scanRepositories' setting.")); + continue; } - } catch (err) { - // noop + + promises.push(this.openRepository(path.join(root, possibleRepositoryPath))); } - } + + await Promise.all(promises); + })); } private onPossibleGitRepositoryChange(uri: Uri): void { + const config = workspace.getConfiguration('git'); + const autoRepositoryDetection = config.get('autoRepositoryDetection'); + + if (autoRepositoryDetection === false) { + return; + } + this.eventuallyScanPossibleGitRepository(uri.fsPath.replace(/\.git.*$/, '')); } @@ -245,16 +260,12 @@ export class Model { } const dotGit = await this.git.getRepositoryDotGit(repositoryRoot); - const repository = new Repository(this.git.open(repositoryRoot, dotGit), this.globalState, this.outputChannel); + const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this.globalState, this.outputChannel); this.open(repository); await repository.status(); } catch (err) { - if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) { - return; - } - - // console.error('Failed to find repository:', err); + // noop } } @@ -447,6 +458,24 @@ export class Model { return undefined; } + registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable { + this.remoteSourceProviders.add(provider); + this._onDidAddRemoteSourceProvider.fire(provider); + + return toDisposable(() => { + this.remoteSourceProviders.delete(provider); + this._onDidRemoveRemoteSourceProvider.fire(provider); + }); + } + + registerCredentialsProvider(provider: CredentialsProvider): Disposable { + return this.askpass.registerCredentialsProvider(provider); + } + + getRemoteProviders(): RemoteSourceProvider[] { + return [...this.remoteSourceProviders.values()]; + } + dispose(): void { const openRepositories = [...this.openRepositories]; openRepositories.forEach(r => r.dispose()); diff --git a/plugins/textmate/lib/bundles/git/src/repository.ts b/plugins/textmate/lib/bundles/git/src/repository.ts index 4f1d21796aba..44a8858c63d0 100644 --- a/plugins/textmate/lib/bundles/git/src/repository.ts +++ b/plugins/textmate/lib/bundles/git/src/repository.ts @@ -7,7 +7,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, Decoration } from 'vscode'; import * as nls from 'vscode-nls'; -import { Branch, Change, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status, CommitOptions } from './api/git'; +import { Branch, Change, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status, CommitOptions, BranchQuery } from './api/git'; import { AutoFetcher } from './autofetch'; import { debounce, memoize, throttle } from './decorators'; import { Commit, ForcePushMode, GitError, Repository as BaseRepository, Stash, Submodule, LogFileOptions } from './git'; @@ -16,6 +16,7 @@ import { toGitUri } from './uri'; import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, onceEvent } from './util'; import { IFileWatcher, watch } from './watch'; import { Log, LogLevel } from './log'; +import { IRemoteSourceProviderRegistry } from './remoteProvider'; const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); @@ -251,11 +252,13 @@ export class Resource implements SourceControlResourceState { } get resourceDecoration(): Decoration { - const title = this.tooltip; - const letter = this.letter; - const color = this.color; - const priority = this.priority; - return { bubble: true, title, letter, color, priority }; + return { + bubble: this.type !== Status.DELETED && this.type !== Status.INDEX_DELETED, + title: this.tooltip, + letter: this.letter, + color: this.color, + priority: this.priority + }; } constructor( @@ -279,6 +282,7 @@ export const enum Operation { Clean = 'Clean', Branch = 'Branch', GetBranch = 'GetBranch', + GetBranches = 'GetBranches', SetBranchUpstream = 'SetBranchUpstream', HashObject = 'HashObject', Checkout = 'Checkout', @@ -303,6 +307,7 @@ export const enum Operation { CheckIgnore = 'CheckIgnore', GetObjectDetails = 'GetObjectDetails', SubmoduleUpdate = 'SubmoduleUpdate', + RebaseAbort = 'RebaseAbort', RebaseContinue = 'RebaseContinue', FindTrackingBranches = 'GetTracking', Apply = 'Apply', @@ -677,6 +682,7 @@ export class Repository implements Disposable { constructor( private readonly repository: BaseRepository, + remoteSourceProviderRegistry: IRemoteSourceProviderRegistry, globalState: Memento, outputChannel: OutputChannel ) { @@ -743,6 +749,15 @@ export class Repository implements Disposable { const onConfigListenerForUntracked = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.untrackedChanges', root)); onConfigListenerForUntracked(this.updateModelState, this, this.disposables); + const updateInputBoxVisibility = () => { + const config = workspace.getConfiguration('git', root); + this._sourceControl.inputBox.visible = config.get('showCommitInput', true); + }; + + const onConfigListenerForInputBoxVisibility = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.showCommitInput', root)); + onConfigListenerForInputBoxVisibility(updateInputBoxVisibility, this, this.disposables); + updateInputBoxVisibility(); + this.mergeGroup.hideWhenEmpty = true; this.untrackedGroup.hideWhenEmpty = true; @@ -763,7 +778,7 @@ export class Repository implements Disposable { } }, null, this.disposables); - const statusBar = new StatusBarCommands(this); + const statusBar = new StatusBarCommands(this, remoteSourceProviderRegistry); this.disposables.push(statusBar); statusBar.onDidChange(() => this._sourceControl.statusBarCommands = statusBar.commands, null, this.disposables); this._sourceControl.statusBarCommands = statusBar.commands; @@ -1039,6 +1054,10 @@ export class Repository implements Disposable { return await this.run(Operation.GetBranch, () => this.repository.getBranch(name)); } + async getBranches(query: BranchQuery): Promise { + return await this.run(Operation.GetBranches, () => this.repository.getBranches(query)); + } + async setBranchUpstream(name: string, upstream: string): Promise { await this.run(Operation.SetBranchUpstream, () => this.repository.setBranchUpstream(name, upstream)); } @@ -1087,6 +1106,10 @@ export class Repository implements Disposable { await this.run(Operation.Remote, () => this.repository.removeRemote(name)); } + async renameRemote(name: string, newName: string): Promise { + await this.run(Operation.Remote, () => this.repository.renameRemote(name, newName)); + } + @throttle async fetchDefault(options: { silent?: boolean } = {}): Promise { await this.run(Operation.Fetch, () => this.repository.fetch(options)); @@ -1318,6 +1341,10 @@ export class Repository implements Disposable { }); } + async rebaseAbort(): Promise { + await this.run(Operation.RebaseAbort, async () => await this.repository.rebaseAbort()); + } + checkIgnore(filePaths: string[]): Promise> { return this.run(Operation.CheckIgnore, () => { return new Promise>((resolve, reject) => { diff --git a/plugins/textmate/lib/bundles/git/src/statusbar.ts b/plugins/textmate/lib/bundles/git/src/statusbar.ts index 7f858933702f..760a507a8f96 100644 --- a/plugins/textmate/lib/bundles/git/src/statusbar.ts +++ b/plugins/textmate/lib/bundles/git/src/statusbar.ts @@ -7,7 +7,8 @@ import { Disposable, Command, EventEmitter, Event, workspace, Uri } from 'vscode import { Repository, Operation } from './repository'; import { anyEvent, dispose, filterEvent } from './util'; import * as nls from 'vscode-nls'; -import { Branch } from './api/git'; +import { Branch, RemoteSourceProvider } from './api/git'; +import { IRemoteSourceProviderRegistry } from './remoteProvider'; const localize = nls.loadMessageBundle(); @@ -39,41 +40,45 @@ class CheckoutStatusBar { } interface SyncStatusBarState { - enabled: boolean; - isSyncRunning: boolean; - hasRemotes: boolean; - HEAD: Branch | undefined; + readonly enabled: boolean; + readonly isSyncRunning: boolean; + readonly hasRemotes: boolean; + readonly HEAD: Branch | undefined; + readonly remoteSourceProviders: RemoteSourceProvider[]; } class SyncStatusBar { - private static StartState: SyncStatusBarState = { - enabled: true, - isSyncRunning: false, - hasRemotes: false, - HEAD: undefined - }; - private _onDidChange = new EventEmitter(); get onDidChange(): Event { return this._onDidChange.event; } private disposables: Disposable[] = []; - private _state: SyncStatusBarState = SyncStatusBar.StartState; + private _state: SyncStatusBarState; private get state() { return this._state; } private set state(state: SyncStatusBarState) { this._state = state; this._onDidChange.fire(); } - constructor(private repository: Repository) { - repository.onDidRunGitStatus(this.onModelChange, this, this.disposables); - repository.onDidChangeOperations(this.onOperationsChange, this, this.disposables); + constructor(private repository: Repository, private remoteSourceProviderRegistry: IRemoteSourceProviderRegistry) { + repository.onDidRunGitStatus(this.onDidRunGitStatus, this, this.disposables); + repository.onDidChangeOperations(this.onDidChangeOperations, this, this.disposables); + + anyEvent(remoteSourceProviderRegistry.onDidAddRemoteSourceProvider, remoteSourceProviderRegistry.onDidRemoveRemoteSourceProvider) + (this.onDidChangeRemoteSourceProviders, this, this.disposables); const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.enableStatusBarSync')); onEnablementChange(this.updateEnablement, this, this.disposables); this.updateEnablement(); - this._onDidChange.fire(); + this._state = { + enabled: true, + isSyncRunning: false, + hasRemotes: false, + HEAD: undefined, + remoteSourceProviders: this.remoteSourceProviderRegistry.getRemoteProviders() + .filter(p => !!p.publishRepository) + }; } private updateEnablement(): void { @@ -83,7 +88,7 @@ class SyncStatusBar { this.state = { ... this.state, enabled }; } - private onOperationsChange(): void { + private onDidChangeOperations(): void { const isSyncRunning = this.repository.operations.isRunning(Operation.Sync) || this.repository.operations.isRunning(Operation.Push) || this.repository.operations.isRunning(Operation.Pull); @@ -91,7 +96,7 @@ class SyncStatusBar { this.state = { ...this.state, isSyncRunning }; } - private onModelChange(): void { + private onDidRunGitStatus(): void { this.state = { ...this.state, hasRemotes: this.repository.remotes.length > 0, @@ -99,9 +104,34 @@ class SyncStatusBar { }; } + private onDidChangeRemoteSourceProviders(): void { + this.state = { + ...this.state, + remoteSourceProviders: this.remoteSourceProviderRegistry.getRemoteProviders() + .filter(p => !!p.publishRepository) + }; + } + get command(): Command | undefined { - if (!this.state.enabled || !this.state.hasRemotes) { - return undefined; + if (!this.state.enabled) { + return; + } + + if (!this.state.hasRemotes) { + if (this.state.remoteSourceProviders.length === 0) { + return; + } + + const tooltip = this.state.remoteSourceProviders.length === 1 + ? localize('publish to', "Publish to {0}", this.state.remoteSourceProviders[0].name) + : localize('publish to...', "Publish to..."); + + return { + command: 'git.publish', + title: `$(cloud-upload)`, + tooltip, + arguments: [this.repository.sourceControl] + }; } const HEAD = this.state.HEAD; @@ -152,38 +182,21 @@ class SyncStatusBar { export class StatusBarCommands { + readonly onDidChange: Event; + private syncStatusBar: SyncStatusBar; private checkoutStatusBar: CheckoutStatusBar; private disposables: Disposable[] = []; - constructor(repository: Repository) { - this.syncStatusBar = new SyncStatusBar(repository); + constructor(repository: Repository, remoteSourceProviderRegistry: IRemoteSourceProviderRegistry) { + this.syncStatusBar = new SyncStatusBar(repository, remoteSourceProviderRegistry); this.checkoutStatusBar = new CheckoutStatusBar(repository); - } - - get onDidChange(): Event { - return anyEvent( - this.syncStatusBar.onDidChange, - this.checkoutStatusBar.onDidChange - ); + this.onDidChange = anyEvent(this.syncStatusBar.onDidChange, this.checkoutStatusBar.onDidChange); } get commands(): Command[] { - const result: Command[] = []; - - const checkout = this.checkoutStatusBar.command; - - if (checkout) { - result.push(checkout); - } - - const sync = this.syncStatusBar.command; - - if (sync) { - result.push(sync); - } - - return result; + return [this.checkoutStatusBar.command, this.syncStatusBar.command] + .filter((c): c is Command => !!c); } dispose(): void { diff --git a/plugins/textmate/lib/bundles/json/package.json b/plugins/textmate/lib/bundles/json/package.json index c6cf07e79471..af713956bfd6 100644 --- a/plugins/textmate/lib/bundles/json/package.json +++ b/plugins/textmate/lib/bundles/json/package.json @@ -22,13 +22,13 @@ "extensions": [ ".json", ".bowerrc", - ".jshintrc", ".jscsrc", - ".swcrc", ".webmanifest", ".js.map", ".css.map", + ".ts.map", ".har", + ".jslintrc", ".jsonld" ], "filenames": [ @@ -52,7 +52,10 @@ ".babelrc", ".jsonc", ".eslintrc", - ".eslintrc.json" + ".eslintrc.json", + ".jsfmtrc", + ".jshintrc", + ".swcrc" ], "configuration": "./language-configuration.json" } diff --git a/plugins/textmate/lib/bundles/markdown-basics/syntaxes/markdown.tmLanguage.json b/plugins/textmate/lib/bundles/markdown-basics/syntaxes/markdown.tmLanguage.json index af6042b55941..0df87e91d332 100644 --- a/plugins/textmate/lib/bundles/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/plugins/textmate/lib/bundles/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/7cf9aa7bb76c55428063383610edc0a631230d58", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/a7e4475626a505472c76d18e0a1b3cfcf46f9cf9", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -1715,6 +1715,72 @@ } ] }, + "fenced_code_block_erlang": { + "begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(erlang)((\\s+|:|\\{)[^`~]*)?$)", + "name": "markup.fenced_code.block.markdown", + "end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$", + "beginCaptures": { + "3": { + "name": "punctuation.definition.markdown" + }, + "4": { + "name": "fenced_code.block.language.markdown" + }, + "5": { + "name": "fenced_code.block.language.attributes.markdown" + } + }, + "endCaptures": { + "3": { + "name": "punctuation.definition.markdown" + } + }, + "patterns": [ + { + "begin": "(^|\\G)(\\s*)(.*)", + "while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)", + "contentName": "meta.embedded.block.erlang", + "patterns": [ + { + "include": "source.erlang" + } + ] + } + ] + }, + "fenced_code_block_elixir": { + "begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(elixir)((\\s+|:|\\{)[^`~]*)?$)", + "name": "markup.fenced_code.block.markdown", + "end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$", + "beginCaptures": { + "3": { + "name": "punctuation.definition.markdown" + }, + "4": { + "name": "fenced_code.block.language.markdown" + }, + "5": { + "name": "fenced_code.block.language.attributes.markdown" + } + }, + "endCaptures": { + "3": { + "name": "punctuation.definition.markdown" + } + }, + "patterns": [ + { + "begin": "(^|\\G)(\\s*)(.*)", + "while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)", + "contentName": "meta.embedded.block.elixir", + "patterns": [ + { + "include": "source.elixir" + } + ] + } + ] + }, "fenced_code_block": { "patterns": [ { @@ -1867,6 +1933,12 @@ { "include": "#fenced_code_block_log" }, + { + "include": "#fenced_code_block_erlang" + }, + { + "include": "#fenced_code_block_elixir" + }, { "include": "#fenced_code_block_unknown" } diff --git a/plugins/textmate/lib/bundles/perl/cgmanifest.json b/plugins/textmate/lib/bundles/perl/cgmanifest.json index b7c850dd1aab..83d911076712 100644 --- a/plugins/textmate/lib/bundles/perl/cgmanifest.json +++ b/plugins/textmate/lib/bundles/perl/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "textmate/perl.tmbundle", "repositoryUrl": "https://github.com/textmate/perl.tmbundle", - "commitHash": "d9841a0878239fa43f88c640f8d458590f97e8f5" + "commitHash": "80826abe75250286c2a1a07958e50e8551d3f50c" } }, "licenseDetail": [ diff --git a/plugins/textmate/lib/bundles/powershell/language-configuration.json b/plugins/textmate/lib/bundles/powershell/language-configuration.json index f30c0f5f0510..719b5f81b525 100644 --- a/plugins/textmate/lib/bundles/powershell/language-configuration.json +++ b/plugins/textmate/lib/bundles/powershell/language-configuration.json @@ -12,6 +12,8 @@ ["{", "}"], ["[", "]"], ["(", ")"], + { "open": "@'", "close": "\n'@", "notIn": ["string", "comment"]}, + { "open": "@\"", "close": "\n\"@", "notIn": ["string", "comment"]}, { "open": "\"", "close": "\"", "notIn": ["string"]}, { "open": "'", "close": "'", "notIn": ["string", "comment"]}, ["<#", "#>"] @@ -29,4 +31,4 @@ "end": "^\\s*#[eE]nd[rR]egion\\b" } } -} \ No newline at end of file +} diff --git a/plugins/textmate/lib/bundles/python/cgmanifest.json b/plugins/textmate/lib/bundles/python/cgmanifest.json index 97a9d1d11184..6b1df10ed8fb 100644 --- a/plugins/textmate/lib/bundles/python/cgmanifest.json +++ b/plugins/textmate/lib/bundles/python/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "MagicStack/MagicPython", "repositoryUrl": "https://github.com/MagicStack/MagicPython", - "commitHash": "0b09c1fca238d22e15ac5712d03f9bf6da626f9c" + "commitHash": "b4b2e6eb16fee36aea0788bf0aa1853c25f7d276" } }, "license": "MIT", diff --git a/plugins/textmate/lib/bundles/python/syntaxes/MagicPython.tmLanguage.json b/plugins/textmate/lib/bundles/python/syntaxes/MagicPython.tmLanguage.json index a6920a063051..b8822299e63d 100644 --- a/plugins/textmate/lib/bundles/python/syntaxes/MagicPython.tmLanguage.json +++ b/plugins/textmate/lib/bundles/python/syntaxes/MagicPython.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/MagicStack/MagicPython/commit/0b09c1fca238d22e15ac5712d03f9bf6da626f9c", + "version": "https://github.com/MagicStack/MagicPython/commit/b4b2e6eb16fee36aea0788bf0aa1853c25f7d276", "name": "MagicPython", "scopeName": "source.python", "patterns": [ @@ -31,6 +31,9 @@ { "include": "#function-declaration" }, + { + "include": "#generator" + }, { "include": "#statement-keyword" }, @@ -291,6 +294,9 @@ { "include": "#lambda" }, + { + "include": "#generator" + }, { "include": "#illegal-operator" }, @@ -306,6 +312,9 @@ { "include": "#list" }, + { + "include": "#odd-function-call" + }, { "include": "#round-braces" }, @@ -388,6 +397,9 @@ }, { "include": "#member-access-base" + }, + { + "include": "#member-access-attribute" } ] }, @@ -413,6 +425,11 @@ } ] }, + "member-access-attribute": { + "comment": "Highlight attribute access in otherwise non-specialized cases.", + "name": "meta.attribute.python", + "match": "(?x)\n \\b ([[:alpha:]_]\\w*) \\b\n" + }, "special-names": { "name": "constant.other.caps.python", "match": "(?x)\n \\b\n # we want to see \"enough\", meaning 2 or more upper-case\n # letters in the beginning of the constant\n #\n # for more details refer to:\n # https://github.com/MagicStack/MagicPython/issues/42\n (\n _* [[:upper:]] [_\\d]* [[:upper:]]\n )\n [[:upper:]\\d]* (_\\w*)?\n \\b\n" @@ -459,6 +476,21 @@ } ] }, + "odd-function-call": { + "comment": "A bit obscured function call where there may have been an\narbitrary number of other operations to get the function.\nE.g. \"arr[idx](args)\"\n", + "begin": "(?x)\n (?<= \\] | \\) ) \\s*\n (?=\\()\n", + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.definition.arguments.end.python" + } + }, + "patterns": [ + { + "include": "#function-arguments" + } + ] + }, "round-braces": { "begin": "\\(", "end": "\\)", @@ -1195,6 +1227,26 @@ } ] }, + "generator": { + "comment": "Match \"for ... in\" construct used in generators and for loops to\ncorrectly identify the \"in\" as a control flow keyword.\n", + "begin": "\\bfor\\b", + "beginCaptures": { + "0": { + "name": "keyword.control.flow.python" + } + }, + "end": "\\bin\\b", + "endCaptures": { + "0": { + "name": "keyword.control.flow.python" + } + }, + "patterns": [ + { + "include": "#expression" + } + ] + }, "function-declaration": { "name": "meta.function.python", "begin": "(?x)\n \\s*\n (?:\\b(async) \\s+)? \\b(def)\\s+\n (?=\n [[:alpha:]_][[:word:]]* \\s* \\(\n )\n", @@ -1407,6 +1459,7 @@ "include": "#special-names" }, { + "name": "meta.indexed-name.python", "match": "(?x)\n \\b ([[:alpha:]_]\\w*) \\b\n" } ] @@ -1524,6 +1577,7 @@ }, "function-call": { "name": "meta.function-call.python", + "comment": "Regular function call of the type \"name(args)\"", "begin": "(?x)\n \\b(?=\n ([[:alpha:]_]\\w*) \\s* (\\()\n )\n", "end": "(\\))", "endCaptures": { diff --git a/plugins/textmate/lib/bundles/r/cgmanifest.json b/plugins/textmate/lib/bundles/r/cgmanifest.json index 7cf785d7140b..62f2751e6c90 100644 --- a/plugins/textmate/lib/bundles/r/cgmanifest.json +++ b/plugins/textmate/lib/bundles/r/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "Ikuyadeu/vscode-R", "repositoryUrl": "https://github.com/Ikuyadeu/vscode-R", - "commitHash": "bc79e9245682ee09b4f0b742b927a37702d91b82" + "commitHash": "e03ba9cb9b19412f48c73ea73deb6746d50bbf23" } }, "license": "MIT", - "version": "1.1.8" + "version": "1.3.0" } ], "version": 1 diff --git a/plugins/textmate/lib/bundles/r/syntaxes/r.tmLanguage.json b/plugins/textmate/lib/bundles/r/syntaxes/r.tmLanguage.json index 2b6c4368da97..ad947f628499 100644 --- a/plugins/textmate/lib/bundles/r/syntaxes/r.tmLanguage.json +++ b/plugins/textmate/lib/bundles/r/syntaxes/r.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Ikuyadeu/vscode-R/commit/bc79e9245682ee09b4f0b742b927a37702d91b82", + "version": "https://github.com/Ikuyadeu/vscode-R/commit/e03ba9cb9b19412f48c73ea73deb6746d50bbf23", "name": "R", "scopeName": "source.r", "patterns": [ @@ -168,20 +168,12 @@ "match": "(\\-|\\+|\\*|\\/|%\\/%|%%|%\\*%|%o%|%x%|\\^)", "name": "keyword.operator.arithmetic.r" }, - { - "match": "<=|>=", - "name": "keyword.operator.comparison.r" - }, - { - "match": "==", - "name": "keyword.operator.comarison.r" - }, { "match": "(:=|<-|<<-|->|->>)", "name": "keyword.operator.assignment.r" }, { - "match": "(!=|<>|<|>|%in%)", + "match": "(==|<=|>=|!=|<>|<|>|%in%)", "name": "keyword.operator.comparison.r" }, { diff --git a/plugins/textmate/lib/bundles/ruby/package.json b/plugins/textmate/lib/bundles/ruby/package.json index 4572f2526d8b..1603b171924e 100644 --- a/plugins/textmate/lib/bundles/ruby/package.json +++ b/plugins/textmate/lib/bundles/ruby/package.json @@ -13,7 +13,7 @@ "languages": [{ "id": "ruby", "extensions": [ ".rb", ".rbx", ".rjs", ".gemspec", ".rake", ".ru", ".erb", ".podspec", ".rbi" ], - "filenames": [ "rakefile", "gemfile", "guardfile", "podfile", "capfile" ], + "filenames": [ "rakefile", "gemfile", "guardfile", "podfile", "capfile", "Vagrantfile", ".simplecov" ], "aliases": [ "Ruby", "rb" ], "firstLine": "^#!\\s*/.*\\bruby\\b", "configuration": "./language-configuration.json" diff --git a/plugins/textmate/lib/bundles/search-result/package.json b/plugins/textmate/lib/bundles/search-result/package.json index 6a55968bda16..ffb5321ae4d1 100644 --- a/plugins/textmate/lib/bundles/search-result/package.json +++ b/plugins/textmate/lib/bundles/search-result/package.json @@ -43,8 +43,5 @@ "path": "./syntaxes/searchResult.tmLanguage.json" } ] - }, - "devDependencies": { - "vscode": "^1.1.36" } } diff --git a/plugins/textmate/lib/bundles/search-result/syntaxes/generateTMLanguage.js b/plugins/textmate/lib/bundles/search-result/syntaxes/generateTMLanguage.js index 23e0615a7182..eac084ddbc1c 100644 --- a/plugins/textmate/lib/bundles/search-result/syntaxes/generateTMLanguage.js +++ b/plugins/textmate/lib/bundles/search-result/syntaxes/generateTMLanguage.js @@ -12,7 +12,7 @@ const mappings = [ ['css', 'source.css'], ['dart', 'source.dart'], ['diff', 'source.diff'], - ['dockerfile', 'source.dockerfile', '(?:dockerfile|Dockerfile)'], + ['dockerfile', 'source.dockerfile', '(?:dockerfile|Dockerfile|containerfile|Containerfile)'], ['fs', 'source.fsharp'], ['go', 'source.go'], ['groovy', 'source.groovy'], diff --git a/plugins/textmate/lib/bundles/search-result/yarn.lock b/plugins/textmate/lib/bundles/search-result/yarn.lock index 4ff83ab98bbf..fb57ccd13afb 100644 --- a/plugins/textmate/lib/bundles/search-result/yarn.lock +++ b/plugins/textmate/lib/bundles/search-result/yarn.lock @@ -2,601 +2,3 @@ # yarn lockfile v1 -agent-base@4, agent-base@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" - integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== - dependencies: - es6-promisify "^5.0.0" - -ajv@^6.5.5: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= - dependencies: - es6-promise "^4.0.3" - -escape-string-regexp@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.2: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= - -http-proxy-agent@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" - integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== - dependencies: - agent-base "4" - debug "3.1.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" - integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== - dependencies: - agent-base "^4.3.0" - debug "^3.1.0" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -mime-db@1.40.0: - version "1.40.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" - integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.24" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" - integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== - dependencies: - mime-db "1.40.0" - -minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -mkdirp@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -mocha@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" - integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== - dependencies: - browser-stdout "1.3.1" - commander "2.15.1" - debug "3.1.0" - diff "3.5.0" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.5" - he "1.1.1" - minimatch "3.0.4" - mkdirp "0.5.1" - supports-color "5.4.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -psl@^1.1.24: - version "1.4.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" - integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== - -request@^2.88.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - -safe-buffer@^5.0.1, safe-buffer@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -semver@^5.4.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -source-map-support@^0.5.0: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -supports-color@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== - dependencies: - has-flag "^3.0.0" - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -url-parse@^1.4.4: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -uuid@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vscode-test@^0.4.1: - version "0.4.3" - resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.4.3.tgz#461ebf25fc4bc93d77d982aed556658a2e2b90b8" - integrity sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w== - dependencies: - http-proxy-agent "^2.1.0" - https-proxy-agent "^2.2.1" - -vscode@^1.1.36: - version "1.1.36" - resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.36.tgz#5e1a0d1bf4977d0c7bc5159a9a13d5b104d4b1b6" - integrity sha512-cGFh9jmGLcTapCpPCKvn8aG/j9zVQ+0x5hzYJq5h5YyUXVGa1iamOaB2M2PZXoumQPES4qeAP1FwkI0b6tL4bQ== - dependencies: - glob "^7.1.2" - mocha "^5.2.0" - request "^2.88.0" - semver "^5.4.1" - source-map-support "^0.5.0" - url-parse "^1.4.4" - vscode-test "^0.4.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= diff --git a/plugins/textmate/lib/bundles/shellscript/package.json b/plugins/textmate/lib/bundles/shellscript/package.json index 207ae27aa1b3..50c3ffdb799f 100644 --- a/plugins/textmate/lib/bundles/shellscript/package.json +++ b/plugins/textmate/lib/bundles/shellscript/package.json @@ -13,13 +13,45 @@ "languages": [{ "id": "shellscript", "aliases": ["Shell Script", "shellscript", "bash", "sh", "zsh", "ksh", "csh"], - "extensions": [".sh", ".bash", ".bashrc", ".bash_aliases", ".bash_profile", ".bash_login", ".ebuild", ".install", ".profile", ".bash_logout", ".zsh", ".zshrc", ".zprofile", ".zlogin", ".zlogout", ".zshenv", ".zsh-theme", ".ksh", ".csh", ".cshrc"], + "extensions": [ + ".sh", + ".bash", + ".bashrc", + ".bash_aliases", + ".bash_profile", + ".bash_login", + ".ebuild", + ".install", + ".profile", + ".bash_logout", + ".zsh", + ".zshrc", + ".zprofile", + ".zlogin", + ".zlogout", + ".zshenv", + ".zsh-theme", + ".ksh", + ".csh", + ".cshrc", + ".tcshrc", + ".yashrc", + ".yash_profile" + ], "filenames": [ - "APKBUILD", - "PKGBUILD", - ".envrc" - ], - "firstLine": "^#!.*\\b(bash|zsh|sh|tcsh|ksh|ash|qsh|csh).*|^#\\s*-\\*-[^*]*mode:\\s*shell-script[^*]*-\\*-", + "APKBUILD", + "PKGBUILD", + ".envrc", + ".hushlogin", + "zshrc", + "zshenv", + "zlogin", + "zprofile", + "zlogout", + "bashrc_Apple_Terminal", + "zshrc_Apple_Terminal" + ], + "firstLine": "^#!.*\\b(bash|zsh|sh|ksh|dtksh|pdksh|mksh|ash|dash|yash|sh|csh|jcsh|tcsh|itcsh).*|^#\\s*-\\*-[^*]*mode:\\s*shell-script[^*]*-\\*-", "configuration": "./language-configuration.json", "mimetypes": ["text/x-shellscript"] }], diff --git a/plugins/textmate/lib/bundles/sql/cgmanifest.json b/plugins/textmate/lib/bundles/sql/cgmanifest.json index 859d67822404..56b576cdc79a 100644 --- a/plugins/textmate/lib/bundles/sql/cgmanifest.json +++ b/plugins/textmate/lib/bundles/sql/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "Microsoft/vscode-mssql", "repositoryUrl": "https://github.com/Microsoft/vscode-mssql", - "commitHash": "a542fe96780e6b274adb281810d419a512fb5bb4" + "commitHash": "37a22725186b5b481b2882a78c7b9fe024c13946" } }, "license": "MIT", diff --git a/plugins/textmate/lib/bundles/sql/syntaxes/sql.tmLanguage.json b/plugins/textmate/lib/bundles/sql/syntaxes/sql.tmLanguage.json index d4173da5b23b..778c35071faa 100644 --- a/plugins/textmate/lib/bundles/sql/syntaxes/sql.tmLanguage.json +++ b/plugins/textmate/lib/bundles/sql/syntaxes/sql.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/vscode-mssql/commit/a542fe96780e6b274adb281810d419a512fb5bb4", + "version": "https://github.com/Microsoft/vscode-mssql/commit/37a22725186b5b481b2882a78c7b9fe024c13946", "name": "SQL", "scopeName": "source.sql", "patterns": [ diff --git a/plugins/textmate/lib/bundles/typescript-basics/snippets/typescript.code-snippets b/plugins/textmate/lib/bundles/typescript-basics/snippets/typescript.code-snippets index 0a7195751d82..0b4f448a803a 100644 --- a/plugins/textmate/lib/bundles/typescript-basics/snippets/typescript.code-snippets +++ b/plugins/textmate/lib/bundles/typescript-basics/snippets/typescript.code-snippets @@ -123,7 +123,7 @@ "Throw Exception": { "prefix": "throw", "body": [ - "throw \"$1\";", + "throw new Error(\"$1\");", "$0" ], "description": "Throw Exception" @@ -167,7 +167,16 @@ "}" ], "description": "For-Of Loop" - }, + }, + "For-Await-Of Loop": { + "prefix": "forawaitof", + "body": [ + "for await (const ${1:iterator} of ${2:object}) {", + "\t$0", + "}" + ], + "description": "For-Await-Of Loop" + }, "Function Statement": { "prefix": "function", "body": [ diff --git a/plugins/textmate/loadVSCBundles.sh b/plugins/textmate/loadVSCBundles.sh index 0e81233734f5..038b6e9e9352 100755 --- a/plugins/textmate/loadVSCBundles.sh +++ b/plugins/textmate/loadVSCBundles.sh @@ -51,8 +51,9 @@ cp -r "info.plist" "$ROOT/lib/bundles/kotlin/" cp -r "snippets" "$ROOT/lib/bundles/kotlin/" cp -r "syntaxes" "$ROOT/lib/bundles/kotlin/" -cd ../.. +cd $ROOT +rm -rf $ROOT/temp -# end -rm -rf $ROOT/temp \ No newline at end of file +echo "Applying patch" +git apply $ROOT/bundles.patch \ No newline at end of file