mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-14 01:25:43 -05:00
Enables typescript strict mode
Fixes all the compile/lint issues
This commit is contained in:
@@ -6,7 +6,7 @@ import { BuiltInCommands } from './constants';
|
||||
export class ActiveEditorTracker extends Disposable {
|
||||
|
||||
private _disposable: Disposable;
|
||||
private _resolver: (value?: TextEditor | PromiseLike<TextEditor>) => void;
|
||||
private _resolver: ((value?: TextEditor | PromiseLike<TextEditor>) => void) | undefined;
|
||||
|
||||
constructor() {
|
||||
super(() => this.dispose());
|
||||
@@ -28,11 +28,11 @@ export class ActiveEditorTracker extends Disposable {
|
||||
return this.wait(timeout);
|
||||
}
|
||||
|
||||
async close(): Promise<{}> {
|
||||
async close(): Promise<{} | undefined> {
|
||||
return commands.executeCommand(BuiltInCommands.CloseActiveEditor);
|
||||
}
|
||||
|
||||
async next(): Promise<{}> {
|
||||
async next(): Promise<{} | undefined> {
|
||||
return commands.executeCommand(BuiltInCommands.NextEditor);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,38 +54,38 @@ export class BlameActiveLineController extends Disposable {
|
||||
}
|
||||
|
||||
private _onConfigurationChanged() {
|
||||
const config = workspace.getConfiguration().get<IConfig>(ExtensionKey);
|
||||
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
|
||||
let changed: boolean = false;
|
||||
|
||||
if (!Objects.areEquivalent(config.statusBar, this._config && this._config.statusBar)) {
|
||||
if (!Objects.areEquivalent(cfg.statusBar, this._config && this._config.statusBar)) {
|
||||
changed = true;
|
||||
if (config.statusBar.enabled) {
|
||||
if (cfg.statusBar.enabled) {
|
||||
this._statusBarItem = this._statusBarItem || window.createStatusBarItem(StatusBarAlignment.Right, 1000);
|
||||
this._statusBarItem.command = config.statusBar.command;
|
||||
this._statusBarItem.command = cfg.statusBar.command;
|
||||
}
|
||||
else if (!config.statusBar.enabled && this._statusBarItem) {
|
||||
else if (!cfg.statusBar.enabled && this._statusBarItem) {
|
||||
this._statusBarItem.dispose();
|
||||
this._statusBarItem = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Objects.areEquivalent(config.blame.annotation.activeLine, this._config && this._config.blame.annotation.activeLine)) {
|
||||
if (!Objects.areEquivalent(cfg.blame.annotation.activeLine, this._config && this._config.blame.annotation.activeLine)) {
|
||||
changed = true;
|
||||
if (config.blame.annotation.activeLine !== 'off' && this._editor) {
|
||||
if (cfg.blame.annotation.activeLine !== 'off' && this._editor) {
|
||||
this._editor.setDecorations(activeLineDecoration, []);
|
||||
}
|
||||
}
|
||||
if (!Objects.areEquivalent(config.blame.annotation.activeLineDarkColor, this._config && this._config.blame.annotation.activeLineDarkColor) ||
|
||||
!Objects.areEquivalent(config.blame.annotation.activeLineLightColor, this._config && this._config.blame.annotation.activeLineLightColor)) {
|
||||
if (!Objects.areEquivalent(cfg.blame.annotation.activeLineDarkColor, this._config && this._config.blame.annotation.activeLineDarkColor) ||
|
||||
!Objects.areEquivalent(cfg.blame.annotation.activeLineLightColor, this._config && this._config.blame.annotation.activeLineLightColor)) {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
this._config = config;
|
||||
this._config = cfg;
|
||||
|
||||
if (!changed) return;
|
||||
|
||||
let trackActiveLine = config.statusBar.enabled || config.blame.annotation.activeLine !== 'off';
|
||||
let trackActiveLine = cfg.statusBar.enabled || cfg.blame.annotation.activeLine !== 'off';
|
||||
if (trackActiveLine && !this._activeEditorLineDisposable) {
|
||||
const subscriptions: Disposable[] = [];
|
||||
|
||||
@@ -103,8 +103,8 @@ export class BlameActiveLineController extends Disposable {
|
||||
this._onActiveTextEditorChanged(window.activeTextEditor);
|
||||
}
|
||||
|
||||
private isEditorBlameable(editor: TextEditor): boolean {
|
||||
if (!editor || !editor.document) return false;
|
||||
private isEditorBlameable(editor: TextEditor | undefined): boolean {
|
||||
if (editor === undefined || editor.document === undefined) return false;
|
||||
|
||||
const scheme = editor.document.uri.scheme;
|
||||
if (scheme !== DocumentSchemes.File && scheme !== DocumentSchemes.Git && scheme !== DocumentSchemes.GitLensGit) return false;
|
||||
@@ -114,13 +114,13 @@ export class BlameActiveLineController extends Disposable {
|
||||
return this.git.isEditorBlameable(editor);
|
||||
}
|
||||
|
||||
private async _onActiveTextEditorChanged(editor: TextEditor) {
|
||||
private async _onActiveTextEditorChanged(editor: TextEditor | undefined) {
|
||||
this._currentLine = -1;
|
||||
|
||||
const previousEditor = this._editor;
|
||||
previousEditor && previousEditor.setDecorations(activeLineDecoration, []);
|
||||
|
||||
if (!this.isEditorBlameable(editor)) {
|
||||
if (editor === undefined || !this.isEditorBlameable(editor)) {
|
||||
this.clear(editor);
|
||||
|
||||
this._editor = undefined;
|
||||
@@ -128,7 +128,7 @@ export class BlameActiveLineController extends Disposable {
|
||||
return;
|
||||
}
|
||||
|
||||
this._blameable = editor && editor.document && !editor.document.isDirty;
|
||||
this._blameable = editor !== undefined && editor.document !== undefined && !editor.document.isDirty;
|
||||
this._editor = editor;
|
||||
this._uri = await GitUri.fromUri(editor.document.uri, this.git);
|
||||
const maxLines = this._config.advanced.caching.statusBar.maxLines;
|
||||
@@ -183,29 +183,29 @@ export class BlameActiveLineController extends Disposable {
|
||||
private async _updateBlame(line: number, editor: TextEditor) {
|
||||
line = line - this._uri.offset;
|
||||
|
||||
let commit: GitCommit;
|
||||
let commitLine: IGitCommitLine;
|
||||
let commit: GitCommit | undefined = undefined;
|
||||
let commitLine: IGitCommitLine | undefined = undefined;
|
||||
// Since blame information isn't valid when there are unsaved changes -- don't show any status
|
||||
if (this._blameable && line >= 0) {
|
||||
if (this._useCaching) {
|
||||
const blame = this._blame && await this._blame;
|
||||
if (!blame || !blame.lines.length) {
|
||||
if (blame === undefined || !blame.lines.length) {
|
||||
this.clear(editor);
|
||||
return;
|
||||
}
|
||||
|
||||
commitLine = blame.lines[line];
|
||||
const sha = commitLine && commitLine.sha;
|
||||
commit = sha && blame.commits.get(sha);
|
||||
const sha = commitLine === undefined ? undefined : commitLine.sha;
|
||||
commit = sha === undefined ? undefined : blame.commits.get(sha);
|
||||
}
|
||||
else {
|
||||
const blameLine = await this.git.getBlameForLine(this._uri, line);
|
||||
commitLine = blameLine && blameLine.line;
|
||||
commit = blameLine && blameLine.commit;
|
||||
commitLine = blameLine === undefined ? undefined : blameLine.line;
|
||||
commit = blameLine === undefined ? undefined : blameLine.commit;
|
||||
}
|
||||
}
|
||||
|
||||
if (commit) {
|
||||
if (commit !== undefined && commitLine !== undefined) {
|
||||
this.show(commit, commitLine, editor);
|
||||
}
|
||||
else {
|
||||
@@ -213,7 +213,7 @@ export class BlameActiveLineController extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
clear(editor: TextEditor, previousEditor?: TextEditor) {
|
||||
clear(editor: TextEditor | undefined, previousEditor?: TextEditor) {
|
||||
editor && editor.setDecorations(activeLineDecoration, []);
|
||||
// I have no idea why the decorators sometimes don't get removed, but if they don't try again with a tiny delay
|
||||
if (editor) {
|
||||
@@ -227,7 +227,7 @@ export class BlameActiveLineController extends Disposable {
|
||||
// I have no idea why I need this protection -- but it happens
|
||||
if (!editor.document) return;
|
||||
|
||||
if (this._config.statusBar.enabled) {
|
||||
if (this._config.statusBar.enabled && this._statusBarItem !== undefined) {
|
||||
switch (this._config.statusBar.date) {
|
||||
case 'off':
|
||||
this._statusBarItem.text = `$(git-commit) ${commit.author}`;
|
||||
@@ -284,7 +284,7 @@ export class BlameActiveLineController extends Disposable {
|
||||
const activeLine = this._config.blame.annotation.activeLine;
|
||||
const offset = this._uri.offset;
|
||||
|
||||
const config = {
|
||||
const cfg = {
|
||||
annotation: {
|
||||
sha: true,
|
||||
author: this._config.statusBar.enabled ? false : this._config.blame.annotation.author,
|
||||
@@ -293,10 +293,10 @@ export class BlameActiveLineController extends Disposable {
|
||||
}
|
||||
} as IBlameConfig;
|
||||
|
||||
const annotation = BlameAnnotationFormatter.getAnnotation(config, commit, BlameAnnotationFormat.Unconstrained);
|
||||
const annotation = BlameAnnotationFormatter.getAnnotation(cfg, commit, BlameAnnotationFormat.Unconstrained);
|
||||
|
||||
// Get the full commit message -- since blame only returns the summary
|
||||
let logCommit: GitCommit;
|
||||
let logCommit: GitCommit | undefined = undefined;
|
||||
if (!commit.isUncommitted) {
|
||||
logCommit = await this.git.getLogCommit(this._uri.repoPath, this._uri.fsPath, commit.sha);
|
||||
}
|
||||
@@ -304,17 +304,17 @@ export class BlameActiveLineController extends Disposable {
|
||||
// I have no idea why I need this protection -- but it happens
|
||||
if (!editor.document) return;
|
||||
|
||||
let hoverMessage: string | string[];
|
||||
let hoverMessage: string | string[] | undefined = undefined;
|
||||
if (activeLine !== 'inline') {
|
||||
// If the messages match (or we couldn't find the log), then this is a possible duplicate annotation
|
||||
const possibleDuplicate = !logCommit || logCommit.message === commit.message;
|
||||
// If we don't have a possible dupe or we aren't showing annotations get the hover message
|
||||
if (!commit.isUncommitted && (!possibleDuplicate || !this.annotationController.isAnnotating(editor))) {
|
||||
hoverMessage = BlameAnnotationFormatter.getAnnotationHover(config, blameLine, logCommit || commit);
|
||||
hoverMessage = BlameAnnotationFormatter.getAnnotationHover(cfg, blameLine, logCommit || commit);
|
||||
}
|
||||
}
|
||||
|
||||
let decorationOptions: DecorationOptions;
|
||||
let decorationOptions: DecorationOptions | undefined = undefined;
|
||||
switch (activeLine) {
|
||||
case 'both':
|
||||
case 'inline':
|
||||
@@ -347,7 +347,9 @@ export class BlameActiveLineController extends Disposable {
|
||||
break;
|
||||
}
|
||||
|
||||
decorationOptions && editor.setDecorations(activeLineDecoration, [decorationOptions]);
|
||||
if (decorationOptions !== undefined) {
|
||||
editor.setDecorations(activeLineDecoration, [decorationOptions]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export const BlameDecorations = {
|
||||
margin: '0 0 0 4em'
|
||||
}
|
||||
} as DecorationRenderOptions),
|
||||
highlight: undefined as TextEditorDecorationType
|
||||
highlight: undefined as TextEditorDecorationType | undefined
|
||||
};
|
||||
|
||||
export class BlameAnnotationController extends Disposable {
|
||||
@@ -29,7 +29,7 @@ export class BlameAnnotationController extends Disposable {
|
||||
}
|
||||
|
||||
private _annotationProviders: Map<number, BlameAnnotationProvider> = new Map();
|
||||
private _blameAnnotationsDisposable: Disposable;
|
||||
private _blameAnnotationsDisposable: Disposable | undefined;
|
||||
private _config: IBlameConfig;
|
||||
private _disposable: Disposable;
|
||||
private _whitespaceController: WhitespaceController | undefined;
|
||||
@@ -73,12 +73,12 @@ export class BlameAnnotationController extends Disposable {
|
||||
this._whitespaceController = undefined;
|
||||
}
|
||||
|
||||
const config = workspace.getConfiguration(ExtensionKey).get<IBlameConfig>('blame');
|
||||
const cfg = workspace.getConfiguration(ExtensionKey).get<IBlameConfig>('blame')!;
|
||||
|
||||
if (config.annotation.highlight !== (this._config && this._config.annotation.highlight)) {
|
||||
if (cfg.annotation.highlight !== (this._config && this._config.annotation.highlight)) {
|
||||
BlameDecorations.highlight && BlameDecorations.highlight.dispose();
|
||||
|
||||
switch (config.annotation.highlight) {
|
||||
switch (cfg.annotation.highlight) {
|
||||
case 'gutter':
|
||||
BlameDecorations.highlight = window.createTextEditorDecorationType({
|
||||
dark: {
|
||||
@@ -133,7 +133,7 @@ export class BlameAnnotationController extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
this._config = config;
|
||||
this._config = cfg;
|
||||
}
|
||||
|
||||
async clear(column: number) {
|
||||
|
||||
@@ -24,7 +24,7 @@ export class BlameAnnotationProvider extends Disposable {
|
||||
|
||||
this._blame = this.git.getBlameForFile(this.uri);
|
||||
|
||||
this._config = workspace.getConfiguration(ExtensionKey).get<IBlameConfig>('blame');
|
||||
this._config = workspace.getConfiguration(ExtensionKey).get<IBlameConfig>('blame')!;
|
||||
|
||||
const subscriptions: Disposable[] = [];
|
||||
|
||||
@@ -39,8 +39,12 @@ export class BlameAnnotationProvider extends Disposable {
|
||||
this.editor.setDecorations(BlameDecorations.annotation, []);
|
||||
BlameDecorations.highlight && this.editor.setDecorations(BlameDecorations.highlight, []);
|
||||
// I have no idea why the decorators sometimes don't get removed, but if they don't try again with a tiny delay
|
||||
if (BlameDecorations.highlight) {
|
||||
setTimeout(() => this.editor.setDecorations(BlameDecorations.highlight, []), 1);
|
||||
if (BlameDecorations.highlight !== undefined) {
|
||||
setTimeout(() => {
|
||||
if (BlameDecorations.highlight === undefined) return;
|
||||
|
||||
this.editor.setDecorations(BlameDecorations.highlight, []);
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
catch (ex) { }
|
||||
@@ -64,7 +68,7 @@ export class BlameAnnotationProvider extends Disposable {
|
||||
}
|
||||
|
||||
async provideBlameAnnotation(shaOrLine?: string | number): Promise<boolean> {
|
||||
let whitespacePromise: Promise<void>;
|
||||
let whitespacePromise: Promise<void> | undefined;
|
||||
// HACK: Until https://github.com/Microsoft/vscode/issues/11485 is fixed -- override whitespace (turn off)
|
||||
if (this._config.annotation.style !== BlameAnnotationStyle.Trailing) {
|
||||
whitespacePromise = this.whitespaceController && this.whitespaceController.override();
|
||||
@@ -116,7 +120,7 @@ export class BlameAnnotationProvider extends Disposable {
|
||||
|
||||
const offset = this.uri.offset;
|
||||
|
||||
let sha: string;
|
||||
let sha: string | undefined = undefined;
|
||||
if (typeof shaOrLine === 'string') {
|
||||
sha = shaOrLine;
|
||||
}
|
||||
@@ -149,7 +153,8 @@ export class BlameAnnotationProvider extends Disposable {
|
||||
let count = 0;
|
||||
let lastSha: string;
|
||||
return blame.lines.map(l => {
|
||||
let commit = blame.commits.get(l.sha);
|
||||
const commit = blame.commits.get(l.sha);
|
||||
if (commit === undefined) throw new Error(`Cannot find sha ${l.sha}`);
|
||||
|
||||
let color: string;
|
||||
if (commit.isUncommitted) {
|
||||
@@ -248,7 +253,8 @@ export class BlameAnnotationProvider extends Disposable {
|
||||
}
|
||||
|
||||
return blame.lines.map(l => {
|
||||
let commit = blame.commits.get(l.sha);
|
||||
const commit = blame.commits.get(l.sha);
|
||||
if (commit === undefined) throw new Error(`Cannot find sha ${l.sha}`);
|
||||
|
||||
let color: string;
|
||||
if (commit.isUncommitted) {
|
||||
|
||||
@@ -33,11 +33,11 @@ export class CloseUnchangedFilesCommand extends ActiveEditorCommand {
|
||||
let active = window.activeTextEditor;
|
||||
let editor = active;
|
||||
do {
|
||||
if (editor) {
|
||||
if ((editor.document && editor.document.isDirty) ||
|
||||
uris.some(_ => UriComparer.equals(_, editor.document && editor.document.uri))) {
|
||||
if (editor !== undefined) {
|
||||
if ((editor.document !== undefined && editor.document.isDirty) ||
|
||||
uris.some(_ => UriComparer.equals(_, editor!.document && editor!.document.uri))) {
|
||||
// If we didn't start with a valid editor, set one once we find it
|
||||
if (!active) {
|
||||
if (active === undefined) {
|
||||
active = editor;
|
||||
}
|
||||
editor = await editorTracker.awaitNext(500);
|
||||
@@ -55,7 +55,7 @@ export class CloseUnchangedFilesCommand extends ActiveEditorCommand {
|
||||
}
|
||||
editor = await editorTracker.awaitClose(500);
|
||||
}
|
||||
} while ((!active && !editor) || !TextEditorComparer.equals(active, editor, { useId: true, usePosition: true }));
|
||||
} while ((active === undefined && editor === undefined) || !TextEditorComparer.equals(active, editor, { useId: true, usePosition: true }));
|
||||
|
||||
editorTracker.dispose();
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ export const CommandContext = {
|
||||
Key: 'gitlens:key' as CommandContext
|
||||
};
|
||||
|
||||
|
||||
export function setCommandContext(key: CommandContext | string, value: any) {
|
||||
return commands.executeCommand(BuiltInCommands.SetContext, key, value);
|
||||
}
|
||||
@@ -119,7 +118,7 @@ export abstract class ActiveEditorCommand extends Command {
|
||||
abstract execute(editor: TextEditor, ...args: any[]): any;
|
||||
}
|
||||
|
||||
let lastCommand: { command: string, args: any[] } = undefined;
|
||||
let lastCommand: { command: string, args: any[] } | undefined = undefined;
|
||||
export function getLastCommand() {
|
||||
return lastCommand;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ export class DiffDirectoryCommand extends ActiveEditorCommand {
|
||||
if (!shaOrBranch1) {
|
||||
const branches = await this.git.getBranches(repoPath);
|
||||
const current = Iterables.find(branches, _ => _.current);
|
||||
if (current == null) return window.showWarningMessage(`Unable to open directory compare`);
|
||||
|
||||
const pick = await BranchesQuickPick.show(branches, `Compare ${current.name} to \u2026`);
|
||||
if (!pick) return undefined;
|
||||
|
||||
@@ -43,7 +43,7 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand {
|
||||
// If the line is uncommitted, find the previous commit and treat it as a DiffWithWorking
|
||||
if (commit.isUncommitted) {
|
||||
uri = commit.uri;
|
||||
commit = new GitCommit(commit.type, commit.repoPath, commit.previousSha, commit.previousFileName, commit.author, commit.date, commit.message);
|
||||
commit = new GitCommit(commit.type, commit.repoPath, commit.previousSha!, commit.previousFileName!, commit.author, commit.date, commit.message);
|
||||
line = (blame.line.line + 1) + gitUri.offset;
|
||||
return commands.executeCommand(Commands.DiffWithWorking, uri, commit, line);
|
||||
}
|
||||
@@ -56,10 +56,10 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand {
|
||||
|
||||
try {
|
||||
const [rhs, lhs] = await Promise.all([
|
||||
this.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha),
|
||||
this.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha!),
|
||||
this.git.getVersionedFile(commit.repoPath, commit.uri.fsPath, commit.sha)
|
||||
]);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(lhs), Uri.file(rhs), `${path.basename(commit.uri.fsPath)} (${commit.shortSha}) ↔ ${path.basename(gitUri.fsPath)} (${gitUri.shortSha})`);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(lhs), Uri.file(rhs), `${path.basename(commit.uri.fsPath)} (${commit.shortSha}) \u2194 ${path.basename(gitUri.fsPath)} (${gitUri.shortSha})`);
|
||||
// TODO: Figure out how to focus the left pane
|
||||
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: line, at: 'center' });
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand {
|
||||
commit = blame.commit;
|
||||
// If the line is uncommitted, find the previous commit
|
||||
if (commit.isUncommitted) {
|
||||
commit = new GitCommit(commit.type, commit.repoPath, commit.previousSha, commit.previousFileName, commit.author, commit.date, commit.message);
|
||||
commit = new GitCommit(commit.type, commit.repoPath, commit.previousSha!, commit.previousFileName!, commit.author, commit.date, commit.message);
|
||||
line = blame.line.line + 1 + gitUri.offset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ export class DiffWithBranchCommand extends ActiveEditorCommand {
|
||||
const line = (editor && editor.selection.active.line) || 0;
|
||||
|
||||
const gitUri = await GitUri.fromUri(uri, this.git);
|
||||
if (gitUri.repoPath === undefined) return undefined;
|
||||
|
||||
const branches = await this.git.getBranches(gitUri.repoPath);
|
||||
const pick = await BranchesQuickPick.show(branches, `Compare ${path.basename(gitUri.fsPath)} to \u2026`, goBackCommand);
|
||||
@@ -36,7 +37,7 @@ export class DiffWithBranchCommand extends ActiveEditorCommand {
|
||||
|
||||
try {
|
||||
const compare = await this.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, branch);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(compare), gitUri.fileUri(), `${path.basename(gitUri.fsPath)} (${branch}) ↔ ${path.basename(gitUri.fsPath)}`);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(compare), gitUri.fileUri(), `${path.basename(gitUri.fsPath)} (${branch}) \u2194 ${path.basename(gitUri.fsPath)}`);
|
||||
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: line, at: 'center' });
|
||||
}
|
||||
catch (ex) {
|
||||
|
||||
@@ -42,7 +42,7 @@ export class DiffWithNextCommand extends ActiveEditorCommand {
|
||||
|
||||
const sha = (commit && commit.sha) || gitUri.sha;
|
||||
|
||||
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, sha ? undefined : 2, rangeOrLine as Range);
|
||||
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, sha ? undefined : 2, rangeOrLine!);
|
||||
if (!log) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`);
|
||||
|
||||
commit = (sha && log.commits.get(sha)) || Iterables.first(log.commits.values());
|
||||
@@ -62,7 +62,7 @@ export class DiffWithNextCommand extends ActiveEditorCommand {
|
||||
this.git.getVersionedFile(commit.repoPath, commit.nextUri.fsPath, commit.nextSha),
|
||||
this.git.getVersionedFile(commit.repoPath, commit.uri.fsPath, commit.sha)
|
||||
]);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(lhs), Uri.file(rhs), `${path.basename(commit.uri.fsPath)} (${commit.shortSha}) ↔ ${path.basename(commit.nextUri.fsPath)} (${commit.nextShortSha})`);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(lhs), Uri.file(rhs), `${path.basename(commit.uri.fsPath)} (${commit.shortSha}) \u2194 ${path.basename(commit.nextUri.fsPath)} (${commit.nextShortSha})`);
|
||||
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: line, at: 'center' });
|
||||
}
|
||||
catch (ex) {
|
||||
|
||||
@@ -43,7 +43,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
|
||||
|
||||
const sha = (commit && commit.sha) || gitUri.sha;
|
||||
|
||||
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, sha ? undefined : 2, rangeOrLine as Range);
|
||||
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, sha ? undefined : 2, rangeOrLine!);
|
||||
if (!log) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`);
|
||||
|
||||
commit = (sha && log.commits.get(sha)) || Iterables.first(log.commits.values());
|
||||
@@ -63,7 +63,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
|
||||
this.git.getVersionedFile(commit.repoPath, commit.uri.fsPath, commit.sha),
|
||||
this.git.getVersionedFile(commit.repoPath, commit.previousUri.fsPath, commit.previousSha)
|
||||
]);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(lhs), Uri.file(rhs), `${path.basename(commit.previousUri.fsPath)} (${commit.previousShortSha}) ↔ ${path.basename(commit.uri.fsPath)} (${commit.shortSha})`);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(lhs), Uri.file(rhs), `${path.basename(commit.previousUri.fsPath)} (${commit.previousShortSha}) \u2194 ${path.basename(commit.uri.fsPath)} (${commit.shortSha})`);
|
||||
// TODO: Figure out how to focus the left pane
|
||||
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: line, at: 'center' });
|
||||
}
|
||||
|
||||
@@ -39,10 +39,11 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
|
||||
const gitUri = await GitUri.fromUri(uri, this.git);
|
||||
|
||||
const workingFileName = await this.git.findWorkingFileName(gitUri.repoPath, gitUri.fsPath);
|
||||
if (workingFileName === undefined) return undefined;
|
||||
|
||||
try {
|
||||
const compare = await this.git.getVersionedFile(commit.repoPath, commit.uri.fsPath, commit.sha);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(compare), Uri.file(path.resolve(gitUri.repoPath, workingFileName)), `${path.basename(commit.uri.fsPath)} (${commit.shortSha}) ↔ ${path.basename(workingFileName)}`);
|
||||
await commands.executeCommand(BuiltInCommands.Diff, Uri.file(compare), Uri.file(path.resolve(gitUri.repoPath, workingFileName)), `${path.basename(commit.uri.fsPath)} (${commit.shortSha}) \u2194 ${path.basename(workingFileName)}`);
|
||||
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: line, at: 'center' });
|
||||
}
|
||||
catch (ex) {
|
||||
|
||||
@@ -16,7 +16,7 @@ export const keys: Keys[] = [
|
||||
'.'
|
||||
];
|
||||
|
||||
export declare type KeyMapping = { [id: string]: (QuickPickItem | (() => Promise<QuickPickItem>)) };
|
||||
export declare type KeyMapping = { [id: string]: (QuickPickItem | (() => Promise<QuickPickItem>) | undefined) };
|
||||
let mappings: KeyMapping[] = [];
|
||||
|
||||
let _instance: Keyboard;
|
||||
@@ -113,7 +113,7 @@ export class Keyboard extends Disposable {
|
||||
return await new KeyboardScope(mapping ? Object.assign(Object.create(null), mapping) : Object.create(null)).begin();
|
||||
}
|
||||
|
||||
async execute(key: Keys): Promise<{}> {
|
||||
async execute(key: Keys): Promise<{} | undefined> {
|
||||
if (!mappings.length) return undefined;
|
||||
|
||||
try {
|
||||
|
||||
@@ -34,7 +34,7 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand {
|
||||
let commit = blame.commit;
|
||||
// If the line is uncommitted, find the previous commit
|
||||
if (commit.isUncommitted) {
|
||||
commit = new GitCommit(commit.type, commit.repoPath, commit.previousSha, commit.previousFileName, commit.author, commit.date, commit.message);
|
||||
commit = new GitCommit(commit.type, commit.repoPath, commit.previousSha!, commit.previousFileName!, commit.author, commit.date, commit.message);
|
||||
}
|
||||
|
||||
const remotes = Arrays.uniqueBy(await this.git.getRemotes(gitUri.repoPath), _ => _.url, _ => !!_.provider);
|
||||
|
||||
@@ -27,7 +27,7 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand {
|
||||
try {
|
||||
const remotes = Arrays.uniqueBy(await this.git.getRemotes(gitUri.repoPath), _ => _.url, _ => !!_.provider);
|
||||
const range = editor && new Range(editor.selection.start.with({ line: editor.selection.start.line + 1 }), editor.selection.end.with({ line: editor.selection.end.line + 1 }));
|
||||
return commands.executeCommand(Commands.OpenInRemote, uri, remotes, 'file', [gitUri.getRelativePath(), branch.name, gitUri.sha, range]);
|
||||
return commands.executeCommand(Commands.OpenInRemote, uri, remotes, 'file', [gitUri.getRelativePath(), branch === undefined ? 'Current' : branch.name, gitUri.sha, range]);
|
||||
}
|
||||
catch (ex) {
|
||||
Logger.error(ex, 'OpenFileInRemoteCommand');
|
||||
|
||||
@@ -11,20 +11,21 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
|
||||
super(Commands.OpenInRemote);
|
||||
}
|
||||
|
||||
async execute(editor: TextEditor, uri?: Uri, remotes?: GitRemote[], type?: RemoteOpenType, args?: string[], goBackCommand?: CommandQuickPickItem) {
|
||||
async execute(editor: TextEditor, uri?: Uri, remotes?: GitRemote[], type?: RemoteOpenType, args: string[] = [], goBackCommand?: CommandQuickPickItem) {
|
||||
if (!(uri instanceof Uri)) {
|
||||
uri = editor && editor.document && editor.document.uri;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!remotes) return undefined;
|
||||
if (remotes === undefined) return undefined;
|
||||
if (type === undefined) throw new Error(`Invalid type ${type}`);
|
||||
|
||||
if (remotes.length === 1) {
|
||||
const command = new OpenRemoteCommandQuickPickItem(remotes[0], type, ...args);
|
||||
return command.execute();
|
||||
}
|
||||
|
||||
let placeHolder: string;
|
||||
let placeHolder: string = '';
|
||||
switch (type) {
|
||||
case 'branch':
|
||||
placeHolder = `open ${args[0]} branch in\u2026`;
|
||||
|
||||
@@ -25,6 +25,7 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand {
|
||||
}
|
||||
|
||||
const gitUri = await GitUri.fromUri(uri, this.git);
|
||||
if (gitUri.repoPath === undefined) return undefined;
|
||||
|
||||
if (!search || searchBy == null) {
|
||||
search = await window.showInputBox({
|
||||
@@ -48,10 +49,15 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand {
|
||||
}
|
||||
|
||||
try {
|
||||
const log = await this.git.getLogForRepoSearch(gitUri.repoPath, search, searchBy);
|
||||
if (searchBy === undefined) {
|
||||
searchBy = GitRepoSearchBy.Message;
|
||||
}
|
||||
|
||||
let originalSearch: string;
|
||||
let placeHolder: string;
|
||||
const log = await this.git.getLogForRepoSearch(gitUri.repoPath, search, searchBy);
|
||||
if (log === undefined) return undefined;
|
||||
|
||||
let originalSearch: string | undefined = undefined;
|
||||
let placeHolder: string | undefined = undefined;
|
||||
switch (searchBy) {
|
||||
case GitRepoSearchBy.Author:
|
||||
originalSearch = `@${search}`;
|
||||
@@ -77,7 +83,7 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand {
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 to commit search`
|
||||
}, Commands.ShowCommitSearch, [gitUri, originalSearch, undefined, goBackCommand]);
|
||||
|
||||
const pick = await CommitsQuickPick.show(this.git, log, placeHolder, currentCommand);
|
||||
const pick = await CommitsQuickPick.show(this.git, log, placeHolder!, currentCommand);
|
||||
if (!pick) return undefined;
|
||||
|
||||
if (pick instanceof CommandQuickPickItem) {
|
||||
|
||||
@@ -22,12 +22,12 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
|
||||
maxCount = this.git.config.advanced.maxQuickHistory;
|
||||
}
|
||||
|
||||
let progressCancellation = branch && BranchHistoryQuickPick.showProgress(branch);
|
||||
let progressCancellation = branch === undefined ? undefined : BranchHistoryQuickPick.showProgress(branch);
|
||||
try {
|
||||
const repoPath = (gitUri && gitUri.repoPath) || this.git.repoPath;
|
||||
if (!repoPath) return window.showWarningMessage(`Unable to show branch history`);
|
||||
if (repoPath === undefined) return window.showWarningMessage(`Unable to show branch history`);
|
||||
|
||||
if (!branch) {
|
||||
if (branch === undefined) {
|
||||
const branches = await this.git.getBranches(repoPath);
|
||||
|
||||
const pick = await BranchesQuickPick.show(branches, `Show history for branch\u2026`);
|
||||
@@ -38,7 +38,7 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
|
||||
}
|
||||
|
||||
branch = pick.branch.name;
|
||||
if (!branch) return undefined;
|
||||
if (branch === undefined) return undefined;
|
||||
|
||||
progressCancellation = BranchHistoryQuickPick.showProgress(branch);
|
||||
}
|
||||
@@ -48,9 +48,9 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
|
||||
if (!log) return window.showWarningMessage(`Unable to show branch history`);
|
||||
}
|
||||
|
||||
if (progressCancellation.token.isCancellationRequested) return undefined;
|
||||
if (progressCancellation !== undefined && progressCancellation.token.isCancellationRequested) return undefined;
|
||||
|
||||
const pick = await BranchHistoryQuickPick.show(this.git, log, gitUri, branch, progressCancellation, goBackCommand, nextPageCommand);
|
||||
const pick = await BranchHistoryQuickPick.show(this.git, log, gitUri, branch, progressCancellation!, goBackCommand, nextPageCommand);
|
||||
if (!pick) return undefined;
|
||||
|
||||
if (pick instanceof CommandQuickPickItem) {
|
||||
|
||||
@@ -21,7 +21,7 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
|
||||
const gitUri = await GitUri.fromUri(uri, this.git);
|
||||
|
||||
let repoPath = gitUri.repoPath;
|
||||
let workingFileName = path.relative(repoPath, gitUri.fsPath);
|
||||
let workingFileName = path.relative(repoPath || '', gitUri.fsPath);
|
||||
|
||||
if (!sha) {
|
||||
if (!editor) return undefined;
|
||||
@@ -48,21 +48,23 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
|
||||
try {
|
||||
if (!commit || (commit.type !== 'branch' && commit.type !== 'stash')) {
|
||||
if (repoLog) {
|
||||
commit = repoLog.commits.get(sha);
|
||||
commit = repoLog.commits.get(sha!);
|
||||
// If we can't find the commit, kill the repoLog
|
||||
if (!commit) {
|
||||
if (commit === undefined) {
|
||||
repoLog = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (!repoLog) {
|
||||
const log = await this.git.getLogForRepo(repoPath, sha, 2);
|
||||
if (!log) return window.showWarningMessage(`Unable to show commit details`);
|
||||
if (repoLog === undefined) {
|
||||
const log = await this.git.getLogForRepo(repoPath!, sha, 2);
|
||||
if (log === undefined) return window.showWarningMessage(`Unable to show commit details`);
|
||||
|
||||
commit = log.commits.get(sha);
|
||||
commit = log.commits.get(sha!);
|
||||
}
|
||||
}
|
||||
|
||||
if (commit === undefined) return window.showWarningMessage(`Unable to show commit details`);
|
||||
|
||||
if (!commit.workingFileName) {
|
||||
commit.workingFileName = workingFileName;
|
||||
}
|
||||
|
||||
@@ -46,24 +46,26 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand
|
||||
try {
|
||||
if (!commit || (commit.type !== 'file' && commit.type !== 'stash')) {
|
||||
if (fileLog) {
|
||||
commit = fileLog.commits.get(sha);
|
||||
commit = fileLog.commits.get(sha!);
|
||||
// If we can't find the commit, kill the fileLog
|
||||
if (!commit) {
|
||||
if (commit === undefined) {
|
||||
fileLog = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileLog) {
|
||||
if (fileLog === undefined) {
|
||||
commit = await this.git.getLogCommit(commit ? commit.repoPath : gitUri.repoPath, gitUri.fsPath, sha, { previous: true });
|
||||
if (!commit) return window.showWarningMessage(`Unable to show commit file details`);
|
||||
if (commit === undefined) return window.showWarningMessage(`Unable to show commit file details`);
|
||||
}
|
||||
}
|
||||
|
||||
if (commit === undefined) return window.showWarningMessage(`Unable to show commit file details`);
|
||||
|
||||
// Attempt to the most recent commit -- so that we can find the real working filename if there was a rename
|
||||
commit.workingFileName = workingFileName;
|
||||
commit.workingFileName = await this.git.findWorkingFileName(commit);
|
||||
|
||||
const shortSha = sha.substring(0, 8);
|
||||
const shortSha = sha!.substring(0, 8);
|
||||
|
||||
if (!goBackCommand) {
|
||||
// Create a command to get back to the commit details
|
||||
|
||||
@@ -18,9 +18,10 @@ export class ShowQuickStashListCommand extends ActiveEditorCachedCommand {
|
||||
|
||||
try {
|
||||
const repoPath = await this.git.getRepoPathFromUri(uri);
|
||||
if (!repoPath) return window.showWarningMessage(`Unable to show stashed changes`);
|
||||
if (repoPath === undefined) return window.showWarningMessage(`Unable to show stashed changes`);
|
||||
|
||||
const stash = await this.git.getStashList(repoPath);
|
||||
if (stash === undefined) return window.showWarningMessage(`Unable to show stashed changes`);
|
||||
|
||||
// Create a command to get back to here
|
||||
const currentCommand = new CommandQuickPickItem({
|
||||
|
||||
@@ -7,9 +7,9 @@ abstract class Comparer<T> {
|
||||
|
||||
class UriComparer extends Comparer<Uri> {
|
||||
|
||||
equals(lhs: Uri, rhs: Uri) {
|
||||
if (!lhs && !rhs) return true;
|
||||
if ((lhs && !rhs) || (!lhs && rhs)) return false;
|
||||
equals(lhs: Uri | undefined, rhs: Uri | undefined) {
|
||||
if (lhs === undefined && rhs === undefined) return true;
|
||||
if (lhs === undefined || rhs === undefined) return false;
|
||||
|
||||
return lhs.scheme === rhs.scheme && lhs.fsPath === rhs.fsPath;
|
||||
}
|
||||
@@ -17,9 +17,9 @@ class UriComparer extends Comparer<Uri> {
|
||||
|
||||
class TextDocumentComparer extends Comparer<TextDocument> {
|
||||
|
||||
equals(lhs: TextDocument, rhs: TextDocument) {
|
||||
if (!lhs && !rhs) return true;
|
||||
if ((lhs && !rhs) || (!lhs && rhs)) return false;
|
||||
equals(lhs: TextDocument | undefined, rhs: TextDocument | undefined) {
|
||||
if (lhs === undefined && rhs === undefined) return true;
|
||||
if (lhs === undefined || rhs === undefined) return false;
|
||||
|
||||
return uriComparer.equals(lhs.uri, rhs.uri);
|
||||
}
|
||||
@@ -27,9 +27,9 @@ class TextDocumentComparer extends Comparer<TextDocument> {
|
||||
|
||||
class TextEditorComparer extends Comparer<TextEditor> {
|
||||
|
||||
equals(lhs: TextEditor, rhs: TextEditor, options: { useId: boolean, usePosition: boolean } = { useId: false, usePosition: false }) {
|
||||
if (!lhs && !rhs) return true;
|
||||
if ((lhs && !rhs) || (!lhs && rhs)) return false;
|
||||
equals(lhs: TextEditor | undefined, rhs: TextEditor | undefined, options: { useId: boolean, usePosition: boolean } = { useId: false, usePosition: false }) {
|
||||
if (lhs === undefined && rhs === undefined) return true;
|
||||
if (lhs === undefined || rhs === undefined) return false;
|
||||
|
||||
if (options.usePosition && (lhs.viewColumn !== rhs.viewColumn)) return false;
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ export interface ICodeLensConfig {
|
||||
}
|
||||
|
||||
export interface ICodeLensLanguageLocation {
|
||||
language: string;
|
||||
language: string | undefined;
|
||||
location: CodeLensLocation;
|
||||
customSymbols?: string[];
|
||||
}
|
||||
|
||||
@@ -30,14 +30,14 @@ export async function activate(context: ExtensionContext) {
|
||||
Logger.configure(context);
|
||||
Telemetry.configure(ApplicationInsightsKey);
|
||||
|
||||
const gitlens = extensions.getExtension(QualifiedExtensionId);
|
||||
const gitlens = extensions.getExtension(QualifiedExtensionId)!;
|
||||
const gitlensVersion = gitlens.packageJSON.version;
|
||||
|
||||
const rootPath = workspace.rootPath && workspace.rootPath.replace(/\\/g, '/');
|
||||
Logger.log(`GitLens(v${gitlensVersion}) active: ${rootPath}`);
|
||||
|
||||
const config = workspace.getConfiguration().get<IConfig>(ExtensionKey);
|
||||
const gitPath = config.advanced.git;
|
||||
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
const gitPath = cfg.advanced.git;
|
||||
|
||||
try {
|
||||
await GitService.getGitPath(gitPath);
|
||||
@@ -114,7 +114,7 @@ export async function activate(context: ExtensionContext) {
|
||||
context.subscriptions.push(new StashSaveCommand(git));
|
||||
context.subscriptions.push(new ToggleCodeLensCommand(git));
|
||||
|
||||
Telemetry.trackEvent('initialized', Objects.flatten(config, 'config', true));
|
||||
Telemetry.trackEvent('initialized', Objects.flatten(cfg, 'config', true));
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
|
||||
@@ -54,8 +54,8 @@ export class Git {
|
||||
return git;
|
||||
}
|
||||
|
||||
static async getRepoPath(cwd: string) {
|
||||
if (!cwd) return '';
|
||||
static async getRepoPath(cwd: string | undefined) {
|
||||
if (cwd === undefined) return '';
|
||||
|
||||
const data = await gitCommand(cwd, 'rev-parse', '--show-toplevel');
|
||||
if (!data) return '';
|
||||
@@ -63,7 +63,7 @@ export class Git {
|
||||
return data.replace(/\r?\n|\r/g, '').replace(/\\/g, '/');
|
||||
}
|
||||
|
||||
static async getVersionedFile(repoPath: string, fileName: string, branchOrSha: string) {
|
||||
static async getVersionedFile(repoPath: string | undefined, fileName: string, branchOrSha: string) {
|
||||
const data = await Git.show(repoPath, fileName, branchOrSha);
|
||||
|
||||
const suffix = Git.isSha(branchOrSha) ? branchOrSha.substring(0, 8) : branchOrSha;
|
||||
@@ -112,7 +112,7 @@ export class Git {
|
||||
}
|
||||
}
|
||||
else {
|
||||
repoPath = this.normalizePath(extract ? path.dirname(fileName) : repoPath);
|
||||
repoPath = this.normalizePath(extract ? path.dirname(fileName) : repoPath!);
|
||||
fileName = this.normalizePath(extract ? path.basename(fileName) : fileName);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ export class Git {
|
||||
|
||||
// Git commands
|
||||
|
||||
static blame(repoPath: string, fileName: string, sha?: string, startLine?: number, endLine?: number) {
|
||||
static blame(repoPath: string | undefined, fileName: string, sha?: string, startLine?: number, endLine?: number) {
|
||||
const [file, root] = Git.splitPath(fileName, repoPath);
|
||||
|
||||
const params = [`blame`, `--root`, `--incremental`];
|
||||
@@ -208,7 +208,7 @@ export class Git {
|
||||
}
|
||||
|
||||
// If we are looking for a specific sha don't exclude merge commits
|
||||
if (!sha || maxCount > 2) {
|
||||
if (!sha || maxCount! > 2) {
|
||||
params.push(`--no-merges`);
|
||||
}
|
||||
else {
|
||||
@@ -236,7 +236,7 @@ export class Git {
|
||||
return gitCommand(root, ...params);
|
||||
}
|
||||
|
||||
static log_search(repoPath: string, search?: string[], maxCount?: number) {
|
||||
static log_search(repoPath: string, search: string[] = [], maxCount?: number) {
|
||||
const params = [...defaultLogParams, `-m`, `-i`];
|
||||
if (maxCount) {
|
||||
params.push(`-n${maxCount}`);
|
||||
@@ -262,7 +262,7 @@ export class Git {
|
||||
return gitCommand(repoPath, 'remote', 'get-url', remote);
|
||||
}
|
||||
|
||||
static show(repoPath: string, fileName: string, branchOrSha: string) {
|
||||
static show(repoPath: string | undefined, fileName: string, branchOrSha: string) {
|
||||
const [file, root] = Git.splitPath(fileName, repoPath);
|
||||
branchOrSha = branchOrSha.replace('^', '');
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Logger } from '../logger';
|
||||
|
||||
export interface BlameabilityChangeEvent {
|
||||
blameable: boolean;
|
||||
editor: TextEditor;
|
||||
editor: TextEditor | undefined;
|
||||
}
|
||||
|
||||
export class GitContextTracker extends Disposable {
|
||||
@@ -18,8 +18,8 @@ export class GitContextTracker extends Disposable {
|
||||
}
|
||||
|
||||
private _disposable: Disposable;
|
||||
private _documentChangeDisposable: Disposable;
|
||||
private _editor: TextEditor;
|
||||
private _documentChangeDisposable: Disposable | undefined;
|
||||
private _editor: TextEditor | undefined;
|
||||
private _gitEnabled: boolean;
|
||||
private _isBlameable: boolean;
|
||||
|
||||
@@ -47,7 +47,7 @@ export class GitContextTracker extends Disposable {
|
||||
}
|
||||
|
||||
_onConfigurationChanged() {
|
||||
const gitEnabled = workspace.getConfiguration('git').get<boolean>('enabled');
|
||||
const gitEnabled = workspace.getConfiguration('git').get<boolean>('enabled', true);
|
||||
if (this._gitEnabled !== gitEnabled) {
|
||||
this._gitEnabled = gitEnabled;
|
||||
setCommandContext(CommandContext.Enabled, gitEnabled);
|
||||
@@ -55,9 +55,9 @@ export class GitContextTracker extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private _onActiveTextEditorChanged(editor: TextEditor) {
|
||||
private _onActiveTextEditorChanged(editor: TextEditor | undefined) {
|
||||
this._editor = editor;
|
||||
this._updateContext(this._gitEnabled && editor);
|
||||
this._updateContext(this._gitEnabled ? editor : undefined);
|
||||
this._subscribeToDocumentChanges();
|
||||
}
|
||||
|
||||
@@ -97,9 +97,9 @@ export class GitContextTracker extends Disposable {
|
||||
this._documentChangeDisposable = undefined;
|
||||
}
|
||||
|
||||
private async _updateContext(editor: TextEditor) {
|
||||
private async _updateContext(editor: TextEditor | undefined) {
|
||||
try {
|
||||
const gitUri = editor && await GitUri.fromUri(editor.document.uri, this.git);
|
||||
const gitUri = editor === undefined ? undefined : await GitUri.fromUri(editor.document.uri, this.git);
|
||||
|
||||
await Promise.all([
|
||||
this._updateEditorContext(gitUri, editor),
|
||||
@@ -131,12 +131,12 @@ export class GitContextTracker extends Disposable {
|
||||
|
||||
private async _updateEditorContext(uri: GitUri | undefined, editor: TextEditor | undefined) {
|
||||
try {
|
||||
const tracked = uri && await this.git.isTracked(uri);
|
||||
const tracked = uri === undefined ? false : await this.git.isTracked(uri);
|
||||
setCommandContext(CommandContext.IsTracked, tracked);
|
||||
|
||||
let blameable = tracked && editor && editor.document && !editor.document.isDirty;
|
||||
let blameable = tracked && (editor !== undefined && editor.document !== undefined && !editor.document.isDirty);
|
||||
if (blameable) {
|
||||
blameable = await this.git.getBlameability(uri);
|
||||
blameable = uri === undefined ? false : await this.git.getBlameability(uri);
|
||||
}
|
||||
|
||||
this._updateBlameability(blameable, true);
|
||||
|
||||
@@ -43,7 +43,7 @@ export class GitUri extends Uri {
|
||||
const commit = commitOrRepoPath;
|
||||
base._fsPath = path.resolve(commit.repoPath, commit.originalFileName || commit.fileName);
|
||||
|
||||
if (!GitService.isUncommitted(commit.sha)) {
|
||||
if (commit.sha !== undefined && !GitService.isUncommitted(commit.sha)) {
|
||||
this.sha = commit.sha;
|
||||
this.repoPath = commit.repoPath;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ export class GitUri extends Uri {
|
||||
}
|
||||
|
||||
getRelativePath(): string {
|
||||
return GitService.normalizePath(path.relative(this.repoPath, this.fsPath));
|
||||
return GitService.normalizePath(path.relative(this.repoPath || '', this.fsPath));
|
||||
}
|
||||
|
||||
static async fromUri(uri: Uri, git: GitService) {
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface IGitCommit {
|
||||
repoPath: string;
|
||||
sha: string;
|
||||
fileName: string;
|
||||
author: string;
|
||||
author?: string;
|
||||
date: Date;
|
||||
message: string;
|
||||
lines: IGitCommitLine[];
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
'use strict';
|
||||
import { Uri } from 'vscode';
|
||||
import { GitCommit, GitCommitType, IGitCommitLine } from './commit';
|
||||
import { IGitStatusFile, GitStatusFileStatus } from './status';
|
||||
import * as path from 'path';
|
||||
|
||||
export class GitLogCommit extends GitCommit {
|
||||
|
||||
fileNames: string;
|
||||
fileStatuses: IGitStatusFile[];
|
||||
nextSha?: string;
|
||||
nextFileName?: string;
|
||||
parentShas: string[];
|
||||
status?: GitStatusFileStatus;
|
||||
|
||||
constructor(
|
||||
type: GitCommitType,
|
||||
repoPath: string,
|
||||
sha: string,
|
||||
fileName: string,
|
||||
author: string,
|
||||
date: Date,
|
||||
message: string,
|
||||
status?: GitStatusFileStatus,
|
||||
fileStatuses?: IGitStatusFile[],
|
||||
lines?: IGitCommitLine[],
|
||||
originalFileName?: string,
|
||||
previousSha?: string,
|
||||
previousFileName?: string
|
||||
) {
|
||||
super(type, repoPath, sha, fileName, author, date, message, lines, originalFileName, previousSha, previousFileName);
|
||||
|
||||
this.fileNames = this.fileName;
|
||||
|
||||
if (fileStatuses) {
|
||||
this.fileStatuses = fileStatuses.filter(_ => !!_.fileName);
|
||||
|
||||
const fileStatus = this.fileStatuses[0];
|
||||
this.fileName = fileStatus.fileName;
|
||||
this.status = fileStatus.status;
|
||||
}
|
||||
else {
|
||||
this.fileStatuses = [{ status: status, fileName: fileName, originalFileName: originalFileName }];
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
get isMerge() {
|
||||
return this.parentShas && this.parentShas.length > 1;
|
||||
}
|
||||
|
||||
get nextShortSha() {
|
||||
return this.nextSha && this.nextSha.substring(0, 8);
|
||||
}
|
||||
|
||||
get nextUri(): Uri {
|
||||
return this.nextFileName ? Uri.file(path.resolve(this.repoPath, this.nextFileName)) : this.uri;
|
||||
}
|
||||
|
||||
getDiffStatus(): string {
|
||||
const added = this.fileStatuses.filter(_ => _.status === 'A' || _.status === '?').length;
|
||||
const deleted = this.fileStatuses.filter(_ => _.status === 'D').length;
|
||||
const changed = this.fileStatuses.filter(_ => _.status !== 'A' && _.status !== '?' && _.status !== 'D').length;
|
||||
return `+${added} ~${changed} -${deleted}`;
|
||||
}
|
||||
'use strict';
|
||||
import { Uri } from 'vscode';
|
||||
import { GitCommit, GitCommitType, IGitCommitLine } from './commit';
|
||||
import { IGitStatusFile, GitStatusFileStatus } from './status';
|
||||
import * as path from 'path';
|
||||
|
||||
export class GitLogCommit extends GitCommit {
|
||||
|
||||
fileNames: string;
|
||||
fileStatuses: IGitStatusFile[];
|
||||
nextSha?: string;
|
||||
nextFileName?: string;
|
||||
parentShas: string[];
|
||||
status?: GitStatusFileStatus;
|
||||
|
||||
constructor(
|
||||
type: GitCommitType,
|
||||
repoPath: string,
|
||||
sha: string,
|
||||
fileName: string,
|
||||
author: string,
|
||||
date: Date,
|
||||
message: string,
|
||||
status?: GitStatusFileStatus,
|
||||
fileStatuses?: IGitStatusFile[],
|
||||
lines?: IGitCommitLine[],
|
||||
originalFileName?: string,
|
||||
previousSha?: string,
|
||||
previousFileName?: string
|
||||
) {
|
||||
super(type, repoPath, sha, fileName, author, date, message, lines, originalFileName, previousSha, previousFileName);
|
||||
|
||||
this.fileNames = this.fileName;
|
||||
|
||||
if (fileStatuses) {
|
||||
this.fileStatuses = fileStatuses.filter(_ => !!_.fileName);
|
||||
|
||||
const fileStatus = this.fileStatuses[0];
|
||||
this.fileName = fileStatus.fileName;
|
||||
this.status = fileStatus.status;
|
||||
}
|
||||
else {
|
||||
this.fileStatuses = [{ status: status, fileName: fileName, originalFileName: originalFileName } as IGitStatusFile];
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
get isMerge() {
|
||||
return this.parentShas && this.parentShas.length > 1;
|
||||
}
|
||||
|
||||
get nextShortSha() {
|
||||
return this.nextSha && this.nextSha.substring(0, 8);
|
||||
}
|
||||
|
||||
get nextUri(): Uri {
|
||||
return this.nextFileName ? Uri.file(path.resolve(this.repoPath, this.nextFileName)) : this.uri;
|
||||
}
|
||||
|
||||
getDiffStatus(): string {
|
||||
const added = this.fileStatuses.filter(_ => _.status === 'A' || _.status === '?').length;
|
||||
const deleted = this.fileStatuses.filter(_ => _.status === 'D').length;
|
||||
const changed = this.fileStatuses.filter(_ => _.status !== 'A' && _.status !== '?' && _.status !== 'D').length;
|
||||
return `+${added} ~${changed} -${deleted}`;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ export class GitStashCommit extends GitLogCommit {
|
||||
previousSha?: string,
|
||||
previousFileName?: string
|
||||
) {
|
||||
super('stash', repoPath, sha, fileName, undefined, date, message, status, fileStatuses, lines, originalFileName, previousSha, previousFileName);
|
||||
super('stash', repoPath, sha, fileName, 'You', date, message, status, fileStatuses, lines, originalFileName, previousSha, previousFileName);
|
||||
}
|
||||
|
||||
get shortSha() {
|
||||
|
||||
@@ -10,7 +10,7 @@ interface IBlameEntry {
|
||||
originalLine: number;
|
||||
lineCount: number;
|
||||
|
||||
author?: string;
|
||||
author: string;
|
||||
// authorEmail?: string;
|
||||
authorDate?: string;
|
||||
authorTimeZone?: string;
|
||||
@@ -30,7 +30,7 @@ interface IBlameEntry {
|
||||
|
||||
export class GitBlameParser {
|
||||
|
||||
private static _parseEntries(data: string): IBlameEntry[] {
|
||||
private static _parseEntries(data: string): IBlameEntry[] | undefined {
|
||||
if (!data) return undefined;
|
||||
|
||||
const lines = data.split('\n');
|
||||
@@ -38,7 +38,7 @@ export class GitBlameParser {
|
||||
|
||||
const entries: IBlameEntry[] = [];
|
||||
|
||||
let entry: IBlameEntry;
|
||||
let entry: IBlameEntry | undefined = undefined;
|
||||
let position = -1;
|
||||
while (++position < lines.length) {
|
||||
let lineParts = lines[position].split(' ');
|
||||
@@ -46,13 +46,13 @@ export class GitBlameParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
if (entry === undefined) {
|
||||
entry = {
|
||||
sha: lineParts[0],
|
||||
originalLine: parseInt(lineParts[1], 10) - 1,
|
||||
line: parseInt(lineParts[2], 10) - 1,
|
||||
lineCount: parseInt(lineParts[3], 10)
|
||||
};
|
||||
} as IBlameEntry;
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -116,7 +116,7 @@ export class GitBlameParser {
|
||||
return entries;
|
||||
}
|
||||
|
||||
static parse(data: string, repoPath: string, fileName: string): IGitBlame {
|
||||
static parse(data: string, repoPath: string | undefined, fileName: string): IGitBlame | undefined {
|
||||
const entries = this._parseEntries(data);
|
||||
if (!entries) return undefined;
|
||||
|
||||
@@ -129,24 +129,26 @@ export class GitBlameParser {
|
||||
for (let i = 0, len = entries.length; i < len; i++) {
|
||||
const entry = entries[i];
|
||||
|
||||
if (i === 0 && !repoPath) {
|
||||
if (i === 0 && repoPath === undefined) {
|
||||
// Try to get the repoPath from the most recent commit
|
||||
repoPath = Git.normalizePath(fileName.replace(fileName.startsWith('/') ? `/${entry.fileName}` : entry.fileName, ''));
|
||||
repoPath = Git.normalizePath(fileName.replace(fileName.startsWith('/') ? `/${entry.fileName}` : entry.fileName!, ''));
|
||||
relativeFileName = Git.normalizePath(path.relative(repoPath, fileName));
|
||||
}
|
||||
|
||||
let commit = commits.get(entry.sha);
|
||||
if (!commit) {
|
||||
let author = authors.get(entry.author);
|
||||
if (!author) {
|
||||
author = {
|
||||
name: entry.author,
|
||||
lineCount: 0
|
||||
};
|
||||
authors.set(entry.author, author);
|
||||
if (commit === undefined) {
|
||||
if (entry.author !== undefined) {
|
||||
let author = authors.get(entry.author);
|
||||
if (author === undefined) {
|
||||
author = {
|
||||
name: entry.author,
|
||||
lineCount: 0
|
||||
};
|
||||
authors.set(entry.author, author);
|
||||
}
|
||||
}
|
||||
|
||||
commit = new GitCommit('blame', repoPath, entry.sha, relativeFileName, entry.author, moment(`${entry.authorDate} ${entry.authorTimeZone}`, 'X +-HHmm').toDate(), entry.summary);
|
||||
commit = new GitCommit('blame', repoPath!, entry.sha, relativeFileName!, entry.author, moment(`${entry.authorDate} ${entry.authorTimeZone}`, 'X +-HHmm').toDate(), entry.summary!);
|
||||
|
||||
if (relativeFileName !== entry.fileName) {
|
||||
commit.originalFileName = entry.fileName;
|
||||
@@ -176,7 +178,14 @@ export class GitBlameParser {
|
||||
}
|
||||
}
|
||||
|
||||
commits.forEach(c => authors.get(c.author).lineCount += c.lines.length);
|
||||
commits.forEach(c => {
|
||||
if (c.author === undefined) return;
|
||||
|
||||
const author = authors.get(c.author);
|
||||
if (author === undefined) return;
|
||||
|
||||
author.lineCount += c.lines.length;
|
||||
});
|
||||
|
||||
const sortedAuthors: Map<string, IGitAuthor> = new Map();
|
||||
// const values =
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as path from 'path';
|
||||
interface ILogEntry {
|
||||
sha: string;
|
||||
|
||||
author?: string;
|
||||
author: string;
|
||||
authorDate?: string;
|
||||
|
||||
// committer?: string;
|
||||
@@ -29,7 +29,7 @@ const diffRegex = /diff --git a\/(.*) b\/(.*)/;
|
||||
|
||||
export class GitLogParser {
|
||||
|
||||
private static _parseEntries(data: string, type: GitCommitType, maxCount: number | undefined, reverse: boolean): ILogEntry[] {
|
||||
private static _parseEntries(data: string, type: GitCommitType, maxCount: number | undefined, reverse: boolean): ILogEntry[] | undefined {
|
||||
if (!data) return undefined;
|
||||
|
||||
const lines = data.split('\n');
|
||||
@@ -37,7 +37,7 @@ export class GitLogParser {
|
||||
|
||||
const entries: ILogEntry[] = [];
|
||||
|
||||
let entry: ILogEntry;
|
||||
let entry: ILogEntry | undefined = undefined;
|
||||
let position = -1;
|
||||
while (++position < lines.length) {
|
||||
// Since log --reverse doesn't properly honor a max count -- enforce it here
|
||||
@@ -48,12 +48,12 @@ export class GitLogParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
if (entry === undefined) {
|
||||
if (!Git.shaRegex.test(lineParts[0])) continue;
|
||||
|
||||
entry = {
|
||||
sha: lineParts[0]
|
||||
};
|
||||
} as ILogEntry;
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -118,10 +118,12 @@ export class GitLogParser {
|
||||
if (lineParts[0] === 'diff') {
|
||||
diff = true;
|
||||
const matches = diffRegex.exec(line);
|
||||
entry.fileName = matches[1];
|
||||
const originalFileName = matches[2];
|
||||
if (entry.fileName !== originalFileName) {
|
||||
entry.originalFileName = originalFileName;
|
||||
if (matches != null) {
|
||||
entry.fileName = matches[1];
|
||||
const originalFileName = matches[2];
|
||||
if (entry.fileName !== originalFileName) {
|
||||
entry.originalFileName = originalFileName;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -133,7 +135,7 @@ export class GitLogParser {
|
||||
const status = {
|
||||
status: line[0] as GitStatusFileStatus,
|
||||
fileName: line.substring(1),
|
||||
originalFileName: undefined as string
|
||||
originalFileName: undefined
|
||||
} as IGitStatusFile;
|
||||
this._parseFileName(status);
|
||||
|
||||
@@ -164,7 +166,7 @@ export class GitLogParser {
|
||||
return entries;
|
||||
}
|
||||
|
||||
static parse(data: string, type: GitCommitType, repoPath: string | undefined, fileName: string | undefined, sha: string | undefined, maxCount: number | undefined, reverse: boolean, range: Range): IGitLog {
|
||||
static parse(data: string, type: GitCommitType, repoPath: string | undefined, fileName: string | undefined, sha: string | undefined, maxCount: number | undefined, reverse: boolean, range: Range | undefined): IGitLog | undefined {
|
||||
const entries = this._parseEntries(data, type, maxCount, reverse);
|
||||
if (!entries) return undefined;
|
||||
|
||||
@@ -172,7 +174,7 @@ export class GitLogParser {
|
||||
const commits: Map<string, GitLogCommit> = new Map();
|
||||
|
||||
let relativeFileName: string;
|
||||
let recentCommit: GitLogCommit;
|
||||
let recentCommit: GitLogCommit | undefined = undefined;
|
||||
|
||||
if (repoPath !== undefined) {
|
||||
repoPath = Git.normalizePath(repoPath);
|
||||
@@ -184,28 +186,30 @@ export class GitLogParser {
|
||||
|
||||
const entry = entries[i];
|
||||
|
||||
if (i === 0 && type === 'file' && !repoPath) {
|
||||
if (i === 0 && repoPath === undefined && type === 'file' && fileName !== undefined) {
|
||||
// Try to get the repoPath from the most recent commit
|
||||
repoPath = Git.normalizePath(fileName.replace(fileName.startsWith('/') ? `/${entry.fileName}` : entry.fileName, ''));
|
||||
repoPath = Git.normalizePath(fileName.replace(fileName.startsWith('/') ? `/${entry.fileName}` : entry.fileName!, ''));
|
||||
relativeFileName = Git.normalizePath(path.relative(repoPath, fileName));
|
||||
}
|
||||
else {
|
||||
relativeFileName = entry.fileName;
|
||||
relativeFileName = entry.fileName!;
|
||||
}
|
||||
|
||||
let commit = commits.get(entry.sha);
|
||||
if (!commit) {
|
||||
let author = authors.get(entry.author);
|
||||
if (!author) {
|
||||
author = {
|
||||
name: entry.author,
|
||||
lineCount: 0
|
||||
};
|
||||
authors.set(entry.author, author);
|
||||
if (commit === undefined) {
|
||||
if (entry.author !== undefined) {
|
||||
let author = authors.get(entry.author);
|
||||
if (author === undefined) {
|
||||
author = {
|
||||
name: entry.author,
|
||||
lineCount: 0
|
||||
};
|
||||
authors.set(entry.author, author);
|
||||
}
|
||||
}
|
||||
|
||||
commit = new GitLogCommit(type, repoPath, entry.sha, relativeFileName, entry.author, moment(entry.authorDate).toDate(), entry.summary, entry.status, entry.fileStatuses, undefined, entry.originalFileName);
|
||||
commit.parentShas = entry.parentShas;
|
||||
commit = new GitLogCommit(type, repoPath!, entry.sha, relativeFileName, entry.author, moment(entry.authorDate).toDate(), entry.summary!, entry.status, entry.fileStatuses, undefined, entry.originalFileName);
|
||||
commit.parentShas = entry.parentShas!;
|
||||
|
||||
if (relativeFileName !== entry.fileName) {
|
||||
commit.originalFileName = entry.fileName;
|
||||
@@ -217,7 +221,7 @@ export class GitLogParser {
|
||||
// Logger.log(`merge commit? ${entry.sha}`);
|
||||
// }
|
||||
|
||||
if (recentCommit) {
|
||||
if (recentCommit !== undefined) {
|
||||
recentCommit.previousSha = commit.sha;
|
||||
|
||||
// If the commit sha's match (merge commit), just forward it along
|
||||
@@ -232,7 +236,14 @@ export class GitLogParser {
|
||||
recentCommit = commit;
|
||||
}
|
||||
|
||||
commits.forEach(c => authors.get(c.author).lineCount += c.lines.length);
|
||||
commits.forEach(c => {
|
||||
if (c.author === undefined) return;
|
||||
|
||||
const author = authors.get(c.author);
|
||||
if (author === undefined) return;
|
||||
|
||||
author.lineCount += c.lines.length;
|
||||
});
|
||||
|
||||
const sortedAuthors: Map<string, IGitAuthor> = new Map();
|
||||
// const values =
|
||||
@@ -258,10 +269,12 @@ export class GitLogParser {
|
||||
}
|
||||
|
||||
private static _parseFileName(entry: { fileName?: string, originalFileName?: string }) {
|
||||
if (entry.fileName === undefined) return;
|
||||
|
||||
const index = entry.fileName.indexOf('\t') + 1;
|
||||
if (index) {
|
||||
if (index > 0) {
|
||||
const next = entry.fileName.indexOf('\t', index) + 1;
|
||||
if (next) {
|
||||
if (next > 0) {
|
||||
entry.originalFileName = entry.fileName.substring(index, next - 1);
|
||||
entry.fileName = entry.fileName.substring(next);
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ import * as moment from 'moment';
|
||||
interface IStashEntry {
|
||||
sha: string;
|
||||
date?: string;
|
||||
fileNames?: string;
|
||||
fileNames: string;
|
||||
fileStatuses?: IGitStatusFile[];
|
||||
summary?: string;
|
||||
stashName?: string;
|
||||
summary: string;
|
||||
stashName: string;
|
||||
}
|
||||
|
||||
export class GitStashParser {
|
||||
|
||||
private static _parseEntries(data: string): IStashEntry[] {
|
||||
private static _parseEntries(data: string): IStashEntry[] | undefined {
|
||||
if (!data) return undefined;
|
||||
|
||||
const lines = data.split('\n');
|
||||
@@ -22,7 +22,7 @@ export class GitStashParser {
|
||||
|
||||
const entries: IStashEntry[] = [];
|
||||
|
||||
let entry: IStashEntry;
|
||||
let entry: IStashEntry | undefined = undefined;
|
||||
let position = -1;
|
||||
while (++position < lines.length) {
|
||||
let lineParts = lines[position].split(' ');
|
||||
@@ -30,12 +30,12 @@ export class GitStashParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
if (entry === undefined) {
|
||||
if (!Git.shaRegex.test(lineParts[0])) continue;
|
||||
|
||||
entry = {
|
||||
sha: lineParts[0]
|
||||
};
|
||||
} as IStashEntry;
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ export class GitStashParser {
|
||||
const status = {
|
||||
status: line[0] as GitStatusFileStatus,
|
||||
fileName: line.substring(1),
|
||||
originalFileName: undefined as string
|
||||
originalFileName: undefined
|
||||
} as IGitStatusFile;
|
||||
this._parseFileName(status);
|
||||
|
||||
@@ -109,9 +109,9 @@ export class GitStashParser {
|
||||
return entries;
|
||||
}
|
||||
|
||||
static parse(data: string, repoPath: string): IGitStash {
|
||||
static parse(data: string, repoPath: string): IGitStash | undefined {
|
||||
const entries = this._parseEntries(data);
|
||||
if (!entries) return undefined;
|
||||
if (entries === undefined) return undefined;
|
||||
|
||||
const commits: Map<string, GitStashCommit> = new Map();
|
||||
|
||||
@@ -119,8 +119,8 @@ export class GitStashParser {
|
||||
const entry = entries[i];
|
||||
|
||||
let commit = commits.get(entry.sha);
|
||||
if (!commit) {
|
||||
commit = new GitStashCommit(entry.stashName, repoPath, entry.sha, entry.fileNames, moment(entry.date).toDate(), entry.summary, undefined, entry.fileStatuses);
|
||||
if (commit !== undefined) {
|
||||
commit = new GitStashCommit(entry.stashName, repoPath, entry.sha, entry.fileNames, moment(entry.date).toDate(), entry.summary, undefined, entry.fileStatuses) as GitStashCommit;
|
||||
commits.set(entry.sha, commit);
|
||||
}
|
||||
}
|
||||
@@ -132,10 +132,12 @@ export class GitStashParser {
|
||||
}
|
||||
|
||||
private static _parseFileName(entry: { fileName?: string, originalFileName?: string }) {
|
||||
if (entry.fileName === undefined) return;
|
||||
|
||||
const index = entry.fileName.indexOf('\t') + 1;
|
||||
if (index) {
|
||||
if (index > 0) {
|
||||
const next = entry.fileName.indexOf('\t', index) + 1;
|
||||
if (next) {
|
||||
if (next > 0) {
|
||||
entry.originalFileName = entry.fileName.substring(index, next - 1);
|
||||
entry.fileName = entry.fileName.substring(next);
|
||||
}
|
||||
|
||||
@@ -13,20 +13,22 @@ const behindStatusV1Regex = /(?:behind ([0-9]+))/;
|
||||
|
||||
export class GitStatusParser {
|
||||
|
||||
static parse(data: string, repoPath: string, porcelainVersion: number): IGitStatus {
|
||||
static parse(data: string, repoPath: string, porcelainVersion: number): IGitStatus | undefined {
|
||||
if (!data) return undefined;
|
||||
|
||||
const lines = data.split('\n').filter(_ => !!_);
|
||||
if (!lines.length) return undefined;
|
||||
|
||||
const status = {
|
||||
branch: '',
|
||||
repoPath: Git.normalizePath(repoPath),
|
||||
sha: '',
|
||||
state: {
|
||||
ahead: 0,
|
||||
behind: 0
|
||||
},
|
||||
files: []
|
||||
} as IGitStatus;
|
||||
};
|
||||
|
||||
if (porcelainVersion >= 2) {
|
||||
this._parseV2(lines, repoPath, status);
|
||||
@@ -50,10 +52,10 @@ export class GitStatusParser {
|
||||
const upstreamStatus = lineParts.slice(2).join(' ');
|
||||
|
||||
const aheadStatus = aheadStatusV1Regex.exec(upstreamStatus);
|
||||
status.state.ahead = +aheadStatus[1] || 0;
|
||||
status.state.ahead = aheadStatus == null ? 0 : +aheadStatus[1] || 0;
|
||||
|
||||
const behindStatus = behindStatusV1Regex.exec(upstreamStatus);
|
||||
status.state.behind = +behindStatus[1] || 0;
|
||||
status.state.behind = behindStatus == null ? 0 : +behindStatus[1] || 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -97,7 +99,7 @@ export class GitStatusParser {
|
||||
}
|
||||
else {
|
||||
let lineParts = line.split(' ');
|
||||
let entry: IFileStatusEntry;
|
||||
let entry: IFileStatusEntry | undefined = undefined;
|
||||
switch (lineParts[0][0]) {
|
||||
case '1': // normal
|
||||
entry = this._parseFileEntry(lineParts[1], lineParts.slice(8).join(' '));
|
||||
@@ -114,7 +116,7 @@ export class GitStatusParser {
|
||||
break;
|
||||
}
|
||||
|
||||
if (entry) {
|
||||
if (entry !== undefined) {
|
||||
status.files.push(new GitStatusFile(repoPath, entry.status, entry.fileName, entry.staged, entry.originalFileName));
|
||||
}
|
||||
}
|
||||
@@ -130,6 +132,6 @@ export class GitStatusParser {
|
||||
fileName: fileName,
|
||||
originalFileName: originalFileName,
|
||||
staged: !!indexStatus
|
||||
};
|
||||
} as IFileStatusEntry;
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,11 @@ const UrlRegex = /^(?:git:\/\/(.*?)\/|https:\/\/(.*?)\/|http:\/\/(.*?)\/|git@(.*
|
||||
|
||||
export class RemoteProviderFactory {
|
||||
|
||||
static getRemoteProvider(url: string): RemoteProvider {
|
||||
static getRemoteProvider(url: string): RemoteProvider | undefined {
|
||||
try {
|
||||
const match = UrlRegex.exec(url);
|
||||
if (match == null) return undefined;
|
||||
|
||||
const domain = match[1] || match[2] || match[3] || match[4] || match[5];
|
||||
const path = match[6].replace(/\.git/, '');
|
||||
|
||||
|
||||
@@ -26,10 +26,12 @@ export abstract class RemoteProvider {
|
||||
|
||||
protected abstract getUrlForBranch(branch: string): string;
|
||||
protected abstract getUrlForCommit(sha: string): string;
|
||||
protected abstract getUrlForFile(fileName: string, branch: string, sha?: string, range?: Range): string;
|
||||
protected abstract getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string;
|
||||
|
||||
private async _openUrl(url: string): Promise<{}> {
|
||||
return url && commands.executeCommand(BuiltInCommands.Open, Uri.parse(url));
|
||||
private async _openUrl(url: string): Promise<{} | undefined> {
|
||||
if (url === undefined) return undefined;
|
||||
|
||||
return commands.executeCommand(BuiltInCommands.Open, Uri.parse(url));
|
||||
}
|
||||
|
||||
open(type: 'branch', branch: string): Promise<{}>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
import { Functions, Iterables, Strings } from './system';
|
||||
import { CancellationToken, CodeLens, CodeLensProvider, commands, DocumentSelector, Event, EventEmitter, ExtensionContext, Position, Range, SymbolInformation, SymbolKind, TextDocument, Uri, workspace } from 'vscode';
|
||||
import { CancellationToken, CodeLens, CodeLensProvider, Command, commands, DocumentSelector, Event, EventEmitter, ExtensionContext, Position, Range, SymbolInformation, SymbolKind, TextDocument, Uri, workspace } from 'vscode';
|
||||
import { Commands } from './commands';
|
||||
import { BuiltInCommands, DocumentSchemes, ExtensionKey } from './constants';
|
||||
import { CodeLensCommand, CodeLensLocation, IConfig, ICodeLensLanguageLocation } from './configuration';
|
||||
@@ -10,22 +10,22 @@ import * as moment from 'moment';
|
||||
|
||||
export class GitRecentChangeCodeLens extends CodeLens {
|
||||
|
||||
constructor(private blame: () => IGitBlameLines, public uri: GitUri, public symbolKind: SymbolKind, public blameRange: Range, public isFullRange: boolean, range: Range) {
|
||||
constructor(private blame: () => IGitBlameLines | undefined, public uri: GitUri, public symbolKind: SymbolKind, public blameRange: Range, public isFullRange: boolean, range: Range) {
|
||||
super(range);
|
||||
}
|
||||
|
||||
getBlame(): IGitBlameLines {
|
||||
getBlame(): IGitBlameLines | undefined {
|
||||
return this.blame();
|
||||
}
|
||||
}
|
||||
|
||||
export class GitAuthorsCodeLens extends CodeLens {
|
||||
|
||||
constructor(private blame: () => IGitBlameLines, public uri: GitUri, public symbolKind: SymbolKind, public blameRange: Range, public isFullRange: boolean, range: Range) {
|
||||
constructor(private blame: () => IGitBlameLines | undefined, public uri: GitUri, public symbolKind: SymbolKind, public blameRange: Range, public isFullRange: boolean, range: Range) {
|
||||
super(range);
|
||||
}
|
||||
|
||||
getBlame(): IGitBlameLines {
|
||||
getBlame(): IGitBlameLines | undefined {
|
||||
return this.blame();
|
||||
}
|
||||
}
|
||||
@@ -43,11 +43,11 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
private _documentIsDirty: boolean;
|
||||
|
||||
constructor(context: ExtensionContext, private git: GitService) {
|
||||
this._config = workspace.getConfiguration().get<IConfig>(ExtensionKey);
|
||||
this._config = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._config = workspace.getConfiguration().get<IConfig>(ExtensionKey);
|
||||
this._config = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
|
||||
Logger.log('Triggering a reset of the git CodeLens provider');
|
||||
this._onDidChangeCodeLenses.fire();
|
||||
@@ -56,7 +56,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
|
||||
this._documentIsDirty = document.isDirty;
|
||||
|
||||
let languageLocations = this._config.codeLens.languageLocations.find(_ => _.language.toLowerCase() === document.languageId);
|
||||
let languageLocations = this._config.codeLens.languageLocations.find(_ => _.language !== undefined && _.language.toLowerCase() === document.languageId);
|
||||
if (languageLocations == null) {
|
||||
languageLocations = {
|
||||
language: undefined,
|
||||
@@ -72,10 +72,10 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
const gitUri = await GitUri.fromUri(document.uri, this.git);
|
||||
|
||||
const blamePromise = this.git.getBlameForFile(gitUri);
|
||||
let blame: IGitBlame;
|
||||
let blame: IGitBlame | undefined;
|
||||
if (languageLocations.location === CodeLensLocation.Document) {
|
||||
blame = await blamePromise;
|
||||
if (!blame || !blame.lines.length) return lenses;
|
||||
if (blame === undefined || !blame.lines.length) return lenses;
|
||||
}
|
||||
else {
|
||||
const values = await Promise.all([
|
||||
@@ -84,25 +84,25 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
]);
|
||||
|
||||
blame = values[0] as IGitBlame;
|
||||
if (!blame || !blame.lines.length) return lenses;
|
||||
if (blame === undefined || !blame.lines.length) return lenses;
|
||||
|
||||
const symbols = values[1] as SymbolInformation[];
|
||||
Logger.log('GitCodeLensProvider.provideCodeLenses:', `${symbols.length} symbol(s) found`);
|
||||
symbols.forEach(sym => this._provideCodeLens(gitUri, document, sym, languageLocations, blame, lenses));
|
||||
symbols.forEach(sym => this._provideCodeLens(gitUri, document, sym, languageLocations!, blame!, lenses));
|
||||
}
|
||||
|
||||
if (languageLocations.location !== CodeLensLocation.Custom || (languageLocations.customSymbols || []).find(_ => _.toLowerCase() === 'file')) {
|
||||
// Check if we have a lens for the whole document -- if not add one
|
||||
if (!lenses.find(l => l.range.start.line === 0 && l.range.end.line === 0)) {
|
||||
const blameRange = document.validateRange(new Range(0, 1000000, 1000000, 1000000));
|
||||
let blameForRangeFn: () => IGitBlameLines;
|
||||
let blameForRangeFn: (() => IGitBlameLines | undefined) | undefined = undefined;
|
||||
if (this._documentIsDirty || this._config.codeLens.recentChange.enabled) {
|
||||
blameForRangeFn = Functions.once(() => this.git.getBlameForRangeSync(blame, gitUri, blameRange));
|
||||
blameForRangeFn = Functions.once(() => this.git.getBlameForRangeSync(blame!, gitUri, blameRange));
|
||||
lenses.push(new GitRecentChangeCodeLens(blameForRangeFn, gitUri, SymbolKind.File, blameRange, true, new Range(0, 0, 0, blameRange.start.character)));
|
||||
}
|
||||
if (this._config.codeLens.authors.enabled) {
|
||||
if (!blameForRangeFn) {
|
||||
blameForRangeFn = Functions.once(() => this.git.getBlameForRangeSync(blame, gitUri, blameRange));
|
||||
if (blameForRangeFn === undefined) {
|
||||
blameForRangeFn = Functions.once(() => this.git.getBlameForRangeSync(blame!, gitUri, blameRange));
|
||||
}
|
||||
if (!this._documentIsDirty) {
|
||||
lenses.push(new GitAuthorsCodeLens(blameForRangeFn, gitUri, SymbolKind.File, blameRange, true, new Range(0, 1, 0, blameRange.start.character)));
|
||||
@@ -191,7 +191,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
startChar += Math.floor(symbol.name.length / 2);
|
||||
}
|
||||
|
||||
let blameForRangeFn: () => IGitBlameLines;
|
||||
let blameForRangeFn: (() => IGitBlameLines | undefined) | undefined = undefined;
|
||||
if (this._documentIsDirty || this._config.codeLens.recentChange.enabled) {
|
||||
blameForRangeFn = Functions.once(() => this.git.getBlameForRangeSync(blame, gitUri, blameRange));
|
||||
lenses.push(new GitRecentChangeCodeLens(blameForRangeFn, gitUri, symbol.kind, blameRange, false, line.range.with(new Position(line.range.start.line, startChar))));
|
||||
@@ -220,7 +220,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
}
|
||||
|
||||
if (multiline) {
|
||||
if (!blameForRangeFn) {
|
||||
if (blameForRangeFn === undefined) {
|
||||
blameForRangeFn = Functions.once(() => this.git.getBlameForRangeSync(blame, gitUri, blameRange));
|
||||
}
|
||||
if (!this._documentIsDirty) {
|
||||
@@ -250,14 +250,12 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
title = 'Cannot determine authors (unsaved changes)';
|
||||
}
|
||||
|
||||
lens.command = {
|
||||
title: title,
|
||||
command: undefined
|
||||
};
|
||||
lens.command = { title: title } as Command;
|
||||
return lens;
|
||||
}
|
||||
|
||||
const blame = lens.getBlame();
|
||||
if (blame === undefined) return lens;
|
||||
|
||||
const recentCommit = Iterables.first(blame.commits.values());
|
||||
title = `${recentCommit.author}, ${moment(recentCommit.date).fromNow()}`;
|
||||
@@ -280,6 +278,8 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
|
||||
_resolveGitAuthorsCodeLens(lens: GitAuthorsCodeLens, token: CancellationToken): CodeLens {
|
||||
const blame = lens.getBlame();
|
||||
if (blame === undefined) return lens;
|
||||
|
||||
const count = blame.authors.size;
|
||||
let title = `${count} ${count > 1 ? 'authors' : 'author'} (${Iterables.first(blame.authors.values()).name}${count > 1 ? ' and others' : ''})`;
|
||||
if (this._config.codeLens.debug) {
|
||||
@@ -366,7 +366,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
lens.command = {
|
||||
title: title,
|
||||
command: CodeLensCommand.ShowQuickCommitDetails,
|
||||
arguments: [Uri.file(lens.uri.fsPath), commit.sha, commit]
|
||||
arguments: [Uri.file(lens.uri.fsPath), commit === undefined ? undefined : commit.sha, commit]
|
||||
};
|
||||
return lens;
|
||||
}
|
||||
@@ -375,7 +375,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
|
||||
lens.command = {
|
||||
title: title,
|
||||
command: CodeLensCommand.ShowQuickCommitFileDetails,
|
||||
arguments: [Uri.file(lens.uri.fsPath), commit.sha, commit]
|
||||
arguments: [Uri.file(lens.uri.fsPath), commit === undefined ? undefined : commit.sha, commit]
|
||||
};
|
||||
return lens;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export class GitContentProvider implements TextDocumentContentProvider {
|
||||
const data = GitService.fromGitContentUri(uri);
|
||||
const fileName = data.originalFileName || data.fileName;
|
||||
try {
|
||||
let text = await this.git.getVersionedFileText(data.repoPath, fileName, data.sha) as string;
|
||||
let text = await this.git.getVersionedFileText(data.repoPath, fileName, data.sha);
|
||||
if (data.decoration) {
|
||||
text = `${data.decoration}\n${text}`;
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export class GitContentProvider implements TextDocumentContentProvider {
|
||||
catch (ex) {
|
||||
Logger.error(ex, 'GitContentProvider', 'getVersionedFileText');
|
||||
await window.showErrorMessage(`Unable to show Git revision ${data.sha.substring(0, 8)} of '${path.relative(data.repoPath, fileName)}'`);
|
||||
return undefined;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import * as path from 'path';
|
||||
|
||||
export { GitUri };
|
||||
export * from './git/models/models';
|
||||
export { getNameFromRemoteOpenType, RemoteOpenType } from './git/remotes/provider';
|
||||
export { getNameFromRemoteOpenType, RemoteOpenType, RemoteProvider } from './git/remotes/provider';
|
||||
export * from './git/gitContextTracker';
|
||||
|
||||
class UriCacheEntry {
|
||||
@@ -28,8 +28,9 @@ class GitCacheEntry {
|
||||
blame?: ICachedBlame;
|
||||
log?: ICachedLog;
|
||||
|
||||
get hasErrors() {
|
||||
return !!((this.blame && this.blame.errorMessage) || (this.log && this.log.errorMessage));
|
||||
get hasErrors(): boolean {
|
||||
return (this.blame !== undefined && this.blame.errorMessage !== undefined) ||
|
||||
(this.log !== undefined && this.log.errorMessage !== undefined);
|
||||
}
|
||||
|
||||
constructor(public key: string) { }
|
||||
@@ -69,23 +70,25 @@ export class GitService extends Disposable {
|
||||
return this._onDidBlameFail.event;
|
||||
}
|
||||
|
||||
private _gitCache: Map<string, GitCacheEntry> | undefined;
|
||||
private _gitCache: Map<string, GitCacheEntry>;
|
||||
private _remotesCache: Map<string, GitRemote[]>;
|
||||
private _cacheDisposable: Disposable | undefined;
|
||||
private _uriCache: Map<string, UriCacheEntry> | undefined;
|
||||
private _uriCache: Map<string, UriCacheEntry>;
|
||||
|
||||
config: IConfig;
|
||||
private _codeLensProvider: GitCodeLensProvider | undefined;
|
||||
private _codeLensProviderDisposable: Disposable | undefined;
|
||||
private _disposable: Disposable;
|
||||
private _fsWatcher: FileSystemWatcher;
|
||||
private _disposable: Disposable | undefined;
|
||||
private _fsWatcher: FileSystemWatcher | undefined;
|
||||
private _gitignore: Promise<ignore.Ignore>;
|
||||
|
||||
static EmptyPromise: Promise<IGitBlame | IGitLog> = Promise.resolve(undefined);
|
||||
static EmptyPromise: Promise<IGitBlame | IGitLog | undefined> = Promise.resolve(undefined);
|
||||
|
||||
constructor(private context: ExtensionContext, public repoPath: string) {
|
||||
super(() => this.dispose());
|
||||
|
||||
this._gitCache = new Map();
|
||||
this._remotesCache = new Map();
|
||||
this._uriCache = new Map();
|
||||
|
||||
this._onConfigurationChanged();
|
||||
@@ -110,27 +113,24 @@ export class GitService extends Disposable {
|
||||
this._fsWatcher && this._fsWatcher.dispose();
|
||||
this._fsWatcher = undefined;
|
||||
|
||||
this._gitCache && this._gitCache.clear();
|
||||
this._gitCache = undefined;
|
||||
this._remotesCache && this._remotesCache.clear();
|
||||
this._remotesCache = undefined;
|
||||
this._uriCache && this._uriCache.clear();
|
||||
this._uriCache = undefined;
|
||||
this._gitCache.clear();
|
||||
this._remotesCache.clear();
|
||||
this._uriCache.clear();
|
||||
}
|
||||
|
||||
public get UseGitCaching() {
|
||||
return !!this._gitCache;
|
||||
public get UseCaching() {
|
||||
return this.config.advanced.caching.enabled;
|
||||
}
|
||||
|
||||
private _onConfigurationChanged() {
|
||||
const config = workspace.getConfiguration().get<IConfig>(ExtensionKey);
|
||||
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
|
||||
const codeLensChanged = !Objects.areEquivalent(config.codeLens, this.config && this.config.codeLens);
|
||||
const advancedChanged = !Objects.areEquivalent(config.advanced, this.config && this.config.advanced);
|
||||
const codeLensChanged = !Objects.areEquivalent(cfg.codeLens, this.config && this.config.codeLens);
|
||||
const advancedChanged = !Objects.areEquivalent(cfg.advanced, this.config && this.config.advanced);
|
||||
|
||||
if (codeLensChanged) {
|
||||
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
||||
if (config.codeLens.visibility === CodeLensVisibility.Auto && (config.codeLens.recentChange.enabled || config.codeLens.authors.enabled)) {
|
||||
if (cfg.codeLens.visibility === CodeLensVisibility.Auto && (cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled)) {
|
||||
if (this._codeLensProvider) {
|
||||
this._codeLensProvider.reset();
|
||||
}
|
||||
@@ -145,14 +145,11 @@ export class GitService extends Disposable {
|
||||
this._codeLensProvider = undefined;
|
||||
}
|
||||
|
||||
setCommandContext(CommandContext.CanToggleCodeLens, config.codeLens.visibility !== CodeLensVisibility.Off && (config.codeLens.recentChange.enabled || config.codeLens.authors.enabled));
|
||||
setCommandContext(CommandContext.CanToggleCodeLens, cfg.codeLens.visibility !== CodeLensVisibility.Off && (cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled));
|
||||
}
|
||||
|
||||
if (advancedChanged) {
|
||||
if (config.advanced.caching.enabled) {
|
||||
this._gitCache = new Map();
|
||||
this._remotesCache = new Map();
|
||||
|
||||
if (cfg.advanced.caching.enabled) {
|
||||
this._cacheDisposable && this._cacheDisposable.dispose();
|
||||
|
||||
this._fsWatcher = this._fsWatcher || workspace.createFileSystemWatcher('**/.git/index', true, false, true);
|
||||
@@ -172,15 +169,12 @@ export class GitService extends Disposable {
|
||||
this._fsWatcher && this._fsWatcher.dispose();
|
||||
this._fsWatcher = undefined;
|
||||
|
||||
this._gitCache && this._gitCache.clear();
|
||||
this._gitCache = undefined;
|
||||
|
||||
this._remotesCache && this._remotesCache.clear();
|
||||
this._remotesCache = undefined;
|
||||
this._gitCache.clear();
|
||||
this._remotesCache.clear();
|
||||
}
|
||||
|
||||
this._gitignore = new Promise<ignore.Ignore | undefined>((resolve, reject) => {
|
||||
if (!config.advanced.gitignore.enabled) {
|
||||
if (!cfg.advanced.gitignore.enabled) {
|
||||
resolve(undefined);
|
||||
return;
|
||||
}
|
||||
@@ -202,18 +196,18 @@ export class GitService extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
this.config = config;
|
||||
this.config = cfg;
|
||||
}
|
||||
|
||||
private _onGitChanged() {
|
||||
this._gitCache && this._gitCache.clear();
|
||||
this._gitCache.clear();
|
||||
|
||||
this._onDidChangeGitCache.fire();
|
||||
this._codeLensProvider && this._codeLensProvider.reset();
|
||||
}
|
||||
|
||||
private _removeCachedEntry(document: TextDocument, reason: RemoveCacheReason) {
|
||||
if (!this.UseGitCaching) return;
|
||||
if (!this.UseCaching) return;
|
||||
if (document.uri.scheme !== DocumentSchemes.File) return;
|
||||
|
||||
const cacheKey = this.getCacheEntryKey(document.fileName);
|
||||
@@ -240,21 +234,21 @@ export class GitService extends Disposable {
|
||||
return await new Promise<boolean>((resolve, reject) => fs.exists(path.resolve(repoPath, fileName), e => resolve(e)));
|
||||
}
|
||||
|
||||
async findNextCommit(repoPath: string, fileName: string, sha?: string): Promise<GitLogCommit> {
|
||||
async findNextCommit(repoPath: string, fileName: string, sha?: string): Promise<GitLogCommit | undefined> {
|
||||
let log = await this.getLogForFile(repoPath, fileName, sha, 1, undefined, true);
|
||||
let commit = log && Iterables.first(log.commits.values());
|
||||
if (commit) return commit;
|
||||
|
||||
fileName = await this.findNextFileName(repoPath, fileName, sha);
|
||||
if (fileName) {
|
||||
log = await this.getLogForFile(repoPath, fileName, sha, 1, undefined, true);
|
||||
const nextFileName = await this.findNextFileName(repoPath, fileName, sha);
|
||||
if (nextFileName) {
|
||||
log = await this.getLogForFile(repoPath, nextFileName, sha, 1, undefined, true);
|
||||
commit = log && Iterables.first(log.commits.values());
|
||||
}
|
||||
|
||||
return commit;
|
||||
}
|
||||
|
||||
async findNextFileName(repoPath: string, fileName: string, sha?: string): Promise<string> {
|
||||
async findNextFileName(repoPath: string | undefined, fileName: string, sha?: string): Promise<string | undefined> {
|
||||
[fileName, repoPath] = Git.splitPath(fileName, repoPath);
|
||||
|
||||
return (await this._fileExists(repoPath, fileName))
|
||||
@@ -262,7 +256,7 @@ export class GitService extends Disposable {
|
||||
: await this._findNextFileName(repoPath, fileName, sha);
|
||||
}
|
||||
|
||||
async _findNextFileName(repoPath: string, fileName: string, sha?: string): Promise<string> {
|
||||
async _findNextFileName(repoPath: string, fileName: string, sha?: string): Promise<string | undefined> {
|
||||
if (sha === undefined) {
|
||||
// Get the most recent commit for this file name
|
||||
const c = await this.getLogCommit(repoPath, fileName);
|
||||
@@ -282,12 +276,14 @@ export class GitService extends Disposable {
|
||||
return status.fileName;
|
||||
}
|
||||
|
||||
async findWorkingFileName(commit: GitCommit): Promise<string>;
|
||||
async findWorkingFileName(repoPath: string, fileName: string): Promise<string>;
|
||||
async findWorkingFileName(commitOrRepoPath: GitCommit | string, fileName?: string): Promise<string> {
|
||||
let repoPath: string;
|
||||
if (typeof commitOrRepoPath === 'string') {
|
||||
async findWorkingFileName(commit: GitCommit): Promise<string | undefined>;
|
||||
async findWorkingFileName(repoPath: string | undefined, fileName: string): Promise<string | undefined>;
|
||||
async findWorkingFileName(commitOrRepoPath: GitCommit | string | undefined, fileName?: string): Promise<string | undefined> {
|
||||
let repoPath: string | undefined;
|
||||
if (commitOrRepoPath === undefined || typeof commitOrRepoPath === 'string') {
|
||||
repoPath = commitOrRepoPath;
|
||||
if (fileName === undefined) throw new Error('Invalid fileName');
|
||||
|
||||
[fileName] = Git.splitPath(fileName, repoPath);
|
||||
}
|
||||
else {
|
||||
@@ -298,15 +294,15 @@ export class GitService extends Disposable {
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (await this._fileExists(repoPath, fileName)) return fileName;
|
||||
if (await this._fileExists(repoPath!, fileName)) return fileName;
|
||||
|
||||
fileName = await this._findNextFileName(repoPath, fileName);
|
||||
fileName = await this._findNextFileName(repoPath!, fileName);
|
||||
if (fileName === undefined) return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public async getBlameability(uri: GitUri): Promise<boolean> {
|
||||
if (!this.UseGitCaching) return await this.isTracked(uri);
|
||||
if (!this.UseCaching) return await this.isTracked(uri);
|
||||
|
||||
const cacheKey = this.getCacheEntryKey(uri.fsPath);
|
||||
const entry = this._gitCache.get(cacheKey);
|
||||
@@ -321,7 +317,7 @@ export class GitService extends Disposable {
|
||||
const fileName = uri.fsPath;
|
||||
|
||||
let entry: GitCacheEntry | undefined;
|
||||
if (this.UseGitCaching && !uri.sha) {
|
||||
if (this.UseCaching && !uri.sha) {
|
||||
const cacheKey = this.getCacheEntryKey(fileName);
|
||||
entry = this._gitCache.get(cacheKey);
|
||||
|
||||
@@ -347,7 +343,7 @@ export class GitService extends Disposable {
|
||||
return promise;
|
||||
}
|
||||
|
||||
private async _getBlameForFile(uri: GitUri, fileName: string, entry: GitCacheEntry | undefined): Promise<IGitBlame> {
|
||||
private async _getBlameForFile(uri: GitUri, fileName: string, entry: GitCacheEntry | undefined): Promise<IGitBlame | undefined> {
|
||||
const [file, root] = Git.splitPath(fileName, uri.repoPath, false);
|
||||
|
||||
const ignore = await this._gitignore;
|
||||
@@ -387,12 +383,16 @@ export class GitService extends Disposable {
|
||||
async getBlameForLine(uri: GitUri, line: number): Promise<IGitBlameLine | undefined> {
|
||||
Logger.log(`getBlameForLine('${uri.repoPath}', '${uri.fsPath}', ${line}, ${uri.sha})`);
|
||||
|
||||
if (this.UseGitCaching && !uri.sha) {
|
||||
if (this.UseCaching && !uri.sha) {
|
||||
const blame = await this.getBlameForFile(uri);
|
||||
const blameLine = blame && blame.lines[line];
|
||||
if (!blameLine) return undefined;
|
||||
if (blame === undefined) return undefined;
|
||||
|
||||
const blameLine = blame.lines[line];
|
||||
if (blameLine === undefined) return undefined;
|
||||
|
||||
const commit = blame.commits.get(blameLine.sha);
|
||||
if (commit === undefined) return undefined;
|
||||
|
||||
return {
|
||||
author: Object.assign({}, blame.authors.get(commit.author), { lineCount: commit.lines.length }),
|
||||
commit: commit,
|
||||
@@ -454,7 +454,7 @@ export class GitService extends Disposable {
|
||||
commits.set(c.sha, commit);
|
||||
|
||||
let author = authors.get(commit.author);
|
||||
if (!author) {
|
||||
if (author === undefined) {
|
||||
author = {
|
||||
name: commit.author,
|
||||
lineCount: 0
|
||||
@@ -494,14 +494,14 @@ export class GitService extends Disposable {
|
||||
const uri = GitService.toReferenceGitContentUri(c, i + 1, commitCount, c.originalFileName, decoration);
|
||||
locations.push(new Location(uri, new Position(0, 0)));
|
||||
if (c.sha === selectedSha) {
|
||||
locations.push(new Location(uri, new Position(line + 1, 0)));
|
||||
locations.push(new Location(uri, new Position((line || 0) + 1, 0)));
|
||||
}
|
||||
});
|
||||
|
||||
return locations;
|
||||
}
|
||||
|
||||
async getBranch(repoPath: string): Promise<GitBranch> {
|
||||
async getBranch(repoPath: string): Promise<GitBranch | undefined> {
|
||||
Logger.log(`getBranch('${repoPath}')`);
|
||||
|
||||
const data = await Git.branch(repoPath, false);
|
||||
@@ -533,10 +533,10 @@ export class GitService extends Disposable {
|
||||
return entry && entry.uri;
|
||||
}
|
||||
|
||||
async getLogCommit(repoPath: string, fileName: string, options?: { firstIfMissing?: boolean, previous?: boolean }): Promise<GitLogCommit | undefined>;
|
||||
async getLogCommit(repoPath: string, fileName: string, sha: string, options?: { firstIfMissing?: boolean, previous?: boolean }): Promise<GitLogCommit | undefined>;
|
||||
async getLogCommit(repoPath: string, fileName: string, shaOrOptions?: string | { firstIfMissing?: boolean, previous?: boolean }, options?: { firstIfMissing?: boolean, previous?: boolean }): Promise<GitLogCommit | undefined> {
|
||||
let sha: string;
|
||||
async getLogCommit(repoPath: string | undefined, fileName: string, options?: { firstIfMissing?: boolean, previous?: boolean }): Promise<GitLogCommit | undefined>;
|
||||
async getLogCommit(repoPath: string | undefined, fileName: string, sha: string | undefined, options?: { firstIfMissing?: boolean, previous?: boolean }): Promise<GitLogCommit | undefined>;
|
||||
async getLogCommit(repoPath: string | undefined, fileName: string, shaOrOptions?: string | undefined | { firstIfMissing?: boolean, previous?: boolean }, options?: { firstIfMissing?: boolean, previous?: boolean }): Promise<GitLogCommit | undefined> {
|
||||
let sha: string | undefined = undefined;
|
||||
if (typeof shaOrOptions === 'string') {
|
||||
sha = shaOrOptions;
|
||||
}
|
||||
@@ -578,7 +578,7 @@ export class GitService extends Disposable {
|
||||
maxCount = this.config.advanced.maxQuickHistory || 0;
|
||||
}
|
||||
|
||||
let searchArgs: string[];
|
||||
let searchArgs: string[] | undefined = undefined;
|
||||
switch (searchBy) {
|
||||
case GitRepoSearchBy.Author:
|
||||
searchArgs = [`--author=${search}`];
|
||||
@@ -604,11 +604,11 @@ export class GitService extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
getLogForFile(repoPath: string, fileName: string, sha?: string, maxCount?: number, range?: Range, reverse: boolean = false): Promise<IGitLog | undefined> {
|
||||
getLogForFile(repoPath: string | undefined, fileName: string, sha?: string, maxCount?: number, range?: Range, reverse: boolean = false): Promise<IGitLog | undefined> {
|
||||
Logger.log(`getLogForFile('${repoPath}', '${fileName}', ${sha}, ${maxCount}, ${range && `[${range.start.line}, ${range.end.line}]`}, ${reverse})`);
|
||||
|
||||
let entry: GitCacheEntry | undefined;
|
||||
if (this.UseGitCaching && !sha && !range && !maxCount && !reverse) {
|
||||
if (this.UseCaching && !sha && !range && !maxCount && !reverse) {
|
||||
const cacheKey = this.getCacheEntryKey(fileName);
|
||||
entry = this._gitCache.get(cacheKey);
|
||||
|
||||
@@ -634,7 +634,7 @@ export class GitService extends Disposable {
|
||||
return promise;
|
||||
}
|
||||
|
||||
private async _getLogForFile(repoPath: string, fileName: string, sha: string, range: Range, maxCount: number, reverse: boolean, entry: GitCacheEntry | undefined): Promise<IGitLog> {
|
||||
private async _getLogForFile(repoPath: string | undefined, fileName: string, sha: string | undefined, range: Range | undefined, maxCount: number | undefined, reverse: boolean, entry: GitCacheEntry | undefined): Promise<IGitLog | undefined> {
|
||||
const [file, root] = Git.splitPath(fileName, repoPath, false);
|
||||
|
||||
const ignore = await this._gitignore;
|
||||
@@ -683,7 +683,7 @@ export class GitService extends Disposable {
|
||||
const uri = GitService.toReferenceGitContentUri(c, i + 1, commitCount, c.originalFileName, decoration);
|
||||
locations.push(new Location(uri, new Position(0, 0)));
|
||||
if (c.sha === selectedSha) {
|
||||
locations.push(new Location(uri, new Position(line + 1, 0)));
|
||||
locations.push(new Location(uri, new Position((line || 0) + 1, 0)));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -696,21 +696,21 @@ export class GitService extends Disposable {
|
||||
|
||||
Logger.log(`getRemotes('${repoPath}')`);
|
||||
|
||||
if (this.UseGitCaching) {
|
||||
if (this.UseCaching) {
|
||||
const remotes = this._remotesCache.get(repoPath);
|
||||
if (remotes !== undefined) return remotes;
|
||||
}
|
||||
|
||||
const data = await Git.remote(repoPath);
|
||||
const remotes = data.split('\n').filter(_ => !!_).map(_ => new GitRemote(_));
|
||||
if (this.UseGitCaching) {
|
||||
if (this.UseCaching) {
|
||||
this._remotesCache.set(repoPath, remotes);
|
||||
}
|
||||
return remotes;
|
||||
}
|
||||
|
||||
getRepoPath(cwd: string): Promise<string> {
|
||||
return Git.getRepoPath(cwd);
|
||||
return GitService.getRepoPath(cwd);
|
||||
}
|
||||
|
||||
async getRepoPathFromFile(fileName: string): Promise<string | undefined> {
|
||||
@@ -724,24 +724,26 @@ export class GitService extends Disposable {
|
||||
return (await GitUri.fromUri(uri, this)).repoPath || this.repoPath;
|
||||
}
|
||||
|
||||
async getStashList(repoPath: string): Promise<IGitStash> {
|
||||
async getStashList(repoPath: string): Promise<IGitStash | undefined> {
|
||||
Logger.log(`getStash('${repoPath}')`);
|
||||
|
||||
const data = await Git.stash_list(repoPath);
|
||||
return GitStashParser.parse(data, repoPath);
|
||||
}
|
||||
|
||||
async getStatusForFile(repoPath: string, fileName: string): Promise<GitStatusFile> {
|
||||
async getStatusForFile(repoPath: string, fileName: string): Promise<GitStatusFile | undefined> {
|
||||
Logger.log(`getStatusForFile('${repoPath}', '${fileName}')`);
|
||||
|
||||
const porcelainVersion = Git.validateVersion(2, 11) ? 2 : 1;
|
||||
|
||||
const data = await Git.status_file(repoPath, fileName, porcelainVersion);
|
||||
const status = GitStatusParser.parse(data, repoPath, porcelainVersion);
|
||||
return status && status.files.length && status.files[0];
|
||||
if (status === undefined || !status.files.length) return undefined;
|
||||
|
||||
return status.files[0];
|
||||
}
|
||||
|
||||
async getStatusForRepo(repoPath: string): Promise<IGitStatus> {
|
||||
async getStatusForRepo(repoPath: string): Promise<IGitStatus | undefined> {
|
||||
Logger.log(`getStatusForRepo('${repoPath}')`);
|
||||
|
||||
const porcelainVersion = Git.validateVersion(2, 11) ? 2 : 1;
|
||||
@@ -750,12 +752,12 @@ export class GitService extends Disposable {
|
||||
return GitStatusParser.parse(data, repoPath, porcelainVersion);
|
||||
}
|
||||
|
||||
async getVersionedFile(repoPath: string, fileName: string, sha: string) {
|
||||
async getVersionedFile(repoPath: string | undefined, fileName: string, sha: string) {
|
||||
Logger.log(`getVersionedFile('${repoPath}', '${fileName}', ${sha})`);
|
||||
|
||||
const file = await Git.getVersionedFile(repoPath, fileName, sha);
|
||||
const cacheKey = this.getCacheEntryKey(file);
|
||||
const entry = new UriCacheEntry(new GitUri(Uri.file(fileName), { sha, repoPath, fileName }));
|
||||
const entry = new UriCacheEntry(new GitUri(Uri.file(fileName), { sha, repoPath: repoPath!, fileName }));
|
||||
this._uriCache.set(cacheKey, entry);
|
||||
return file;
|
||||
}
|
||||
@@ -792,14 +794,14 @@ export class GitService extends Disposable {
|
||||
async isFileUncommitted(uri: GitUri): Promise<boolean> {
|
||||
Logger.log(`isFileUncommitted('${uri.repoPath}', '${uri.fsPath}')`);
|
||||
|
||||
const status = await this.getStatusForFile(uri.repoPath, uri.fsPath);
|
||||
const status = await this.getStatusForFile(uri.repoPath!, uri.fsPath);
|
||||
return !!status;
|
||||
}
|
||||
|
||||
async isTracked(uri: GitUri): Promise<boolean> {
|
||||
Logger.log(`isFileUncommitted('${uri.repoPath}', '${uri.fsPath}')`);
|
||||
|
||||
const result = await Git.ls_files(uri.repoPath, uri.fsPath);
|
||||
const result = await Git.ls_files(uri.repoPath === undefined ? '' : uri.repoPath, uri.fsPath);
|
||||
return !!result;
|
||||
}
|
||||
|
||||
@@ -849,7 +851,7 @@ export class GitService extends Disposable {
|
||||
return Git.gitInfo().version;
|
||||
}
|
||||
|
||||
static getRepoPath(cwd: string): Promise<string> {
|
||||
static getRepoPath(cwd: string | undefined): Promise<string> {
|
||||
return Git.getRepoPath(cwd);
|
||||
}
|
||||
|
||||
@@ -874,15 +876,15 @@ export class GitService extends Disposable {
|
||||
return Git.normalizePath(fileName, repoPath);
|
||||
}
|
||||
|
||||
static toGitContentUri(sha: string, shortSha: string, fileName: string, repoPath: string, originalFileName: string): Uri;
|
||||
static toGitContentUri(sha: string, shortSha: string, fileName: string, repoPath: string, originalFileName?: string): Uri;
|
||||
static toGitContentUri(commit: GitCommit): Uri;
|
||||
static toGitContentUri(shaOrcommit: string | GitCommit, shortSha?: string, fileName?: string, repoPath?: string, originalFileName?: string): Uri {
|
||||
let data: IGitUriData;
|
||||
if (typeof shaOrcommit === 'string') {
|
||||
data = GitService._toGitUriData({
|
||||
sha: shaOrcommit,
|
||||
fileName: fileName,
|
||||
repoPath: repoPath,
|
||||
fileName: fileName!,
|
||||
repoPath: repoPath!,
|
||||
originalFileName: originalFileName
|
||||
});
|
||||
}
|
||||
@@ -892,8 +894,8 @@ export class GitService extends Disposable {
|
||||
shortSha = shaOrcommit.shortSha;
|
||||
}
|
||||
|
||||
const extension = path.extname(fileName);
|
||||
return Uri.parse(`${DocumentSchemes.GitLensGit}:${path.basename(fileName, extension)}:${shortSha}${extension}?${JSON.stringify(data)}`);
|
||||
const extension = path.extname(fileName!);
|
||||
return Uri.parse(`${DocumentSchemes.GitLensGit}:${path.basename(fileName!, extension)}:${shortSha}${extension}?${JSON.stringify(data)}`);
|
||||
}
|
||||
|
||||
static toReferenceGitContentUri(commit: GitCommit, index: number, commitCount: number, originalFileName?: string, decoration?: string): Uri {
|
||||
@@ -911,7 +913,7 @@ export class GitService extends Disposable {
|
||||
}
|
||||
|
||||
// NOTE: Need to specify an index here, since I can't control the sort order -- just alphabetic or by file location
|
||||
return Uri.parse(`${scheme}:${pad(data.index)} \u2022 ${encodeURIComponent(message)} \u2022 ${moment(commit.date).format('MMM D, YYYY hh:MMa')} \u2022 ${encodeURIComponent(uriPath)}?${JSON.stringify(data)}`);
|
||||
return Uri.parse(`${scheme}:${pad(data.index || 0)} \u2022 ${encodeURIComponent(message)} \u2022 ${moment(commit.date).format('MMM D, YYYY hh:MMa')} \u2022 ${encodeURIComponent(uriPath)}?${JSON.stringify(data)}`);
|
||||
}
|
||||
|
||||
private static _toGitUriData<T extends IGitUriData>(commit: IGitUriData, index?: number, originalFileName?: string, decoration?: string): T {
|
||||
|
||||
@@ -19,6 +19,7 @@ let output: OutputChannel;
|
||||
|
||||
function onConfigurationChanged() {
|
||||
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey);
|
||||
if (cfg === undefined) return;
|
||||
|
||||
if (cfg.debug !== debug || cfg.outputLevel !== level) {
|
||||
debug = cfg.debug;
|
||||
|
||||
@@ -35,7 +35,7 @@ export class BranchHistoryQuickPick {
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 search for commits by message, author, files, or commit id`
|
||||
}, Commands.ShowCommitSearch, [new GitUri(Uri.file(log.repoPath), { fileName: '', repoPath: log.repoPath }), undefined, undefined, currentCommand]));
|
||||
|
||||
let previousPageCommand: CommandQuickPickItem;
|
||||
let previousPageCommand: CommandQuickPickItem | undefined = undefined;
|
||||
|
||||
if (log.truncated || log.sha) {
|
||||
if (log.truncated) {
|
||||
@@ -72,13 +72,14 @@ export class BranchHistoryQuickPick {
|
||||
}, Commands.ShowQuickBranchHistory, [uri, branch, log.maxCount, goBackCommand, undefined, nextPageCommand]);
|
||||
|
||||
const last = Iterables.last(log.commits.values());
|
||||
if (last != null) {
|
||||
previousPageCommand = new CommandQuickPickItem({
|
||||
label: `$(arrow-left) Show Previous Commits`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 shows ${log.maxCount} older commits`
|
||||
}, Commands.ShowQuickBranchHistory, [new GitUri(uri ? uri : last.uri, last), branch, log.maxCount, goBackCommand, undefined, npc]);
|
||||
|
||||
previousPageCommand = new CommandQuickPickItem({
|
||||
label: `$(arrow-left) Show Previous Commits`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 shows ${log.maxCount} older commits`
|
||||
}, Commands.ShowQuickBranchHistory, [new GitUri(uri ? uri : last.uri, last), branch, log.maxCount, goBackCommand, undefined, npc]);
|
||||
|
||||
items.splice(0, 0, previousPageCommand);
|
||||
items.splice(0, 0, previousPageCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export class BranchQuickPickItem implements QuickPickItem {
|
||||
|
||||
constructor(public branch: GitBranch) {
|
||||
this.label = `${branch.current ? '$(check)\u00a0' : '\u00a0\u00a0\u00a0\u00a0'} ${branch.name}`;
|
||||
this.description = branch.remote ? '\u00a0\u00a0 remote branch' : null;
|
||||
this.description = branch.remote ? '\u00a0\u00a0 remote branch' : '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,20 +19,20 @@ export class CommitWithFileStatusQuickPickItem extends OpenFileCommandQuickPickI
|
||||
constructor(commit: GitCommit, status: IGitStatusFile) {
|
||||
const icon = getGitStatusIcon(status.status);
|
||||
|
||||
let directory = GitService.normalizePath(path.dirname(status.fileName));
|
||||
let directory: string | undefined = GitService.normalizePath(path.dirname(status.fileName));
|
||||
if (!directory || directory === '.') {
|
||||
directory = undefined;
|
||||
directory = '';
|
||||
}
|
||||
|
||||
const description = (status.status === 'R' && status.originalFileName)
|
||||
? `${directory || ''} \u00a0\u2190\u00a0 ${status.originalFileName}`
|
||||
? `${directory} \u00a0\u2190\u00a0 ${status.originalFileName}`
|
||||
: directory;
|
||||
|
||||
let sha;
|
||||
let shortSha;
|
||||
if (status.status === 'D') {
|
||||
sha = commit.previousSha;
|
||||
shortSha = commit.previousShortSha;
|
||||
sha = commit.previousSha!;
|
||||
shortSha = commit.previousShortSha!;
|
||||
}
|
||||
else {
|
||||
sha = commit.sha;
|
||||
@@ -56,7 +56,7 @@ export class OpenCommitFilesCommandQuickPickItem extends OpenFilesCommandQuickPi
|
||||
|
||||
constructor(commit: GitLogCommit, item?: QuickPickItem) {
|
||||
const uris = commit.fileStatuses.map(s => (s.status === 'D')
|
||||
? GitService.toGitContentUri(commit.previousSha, commit.previousShortSha, s.fileName, commit.repoPath, s.originalFileName)
|
||||
? GitService.toGitContentUri(commit.previousSha!, commit.previousShortSha!, s.fileName, commit.repoPath, s.originalFileName)
|
||||
: GitService.toGitContentUri(commit.sha, commit.shortSha, s.fileName, commit.repoPath, s.originalFileName));
|
||||
|
||||
super(uris, item || {
|
||||
@@ -74,7 +74,7 @@ export class OpenCommitWorkingTreeFilesCommandQuickPickItem extends OpenFilesCom
|
||||
const uris = commit.fileStatuses.filter(_ => _.status !== 'D').map(_ => GitUri.fromFileStatus(_, repoPath));
|
||||
super(uris, item || {
|
||||
label: `$(file-symlink-file) Open Changed Working Files`,
|
||||
description: undefined
|
||||
description: ''
|
||||
//detail: `Opens all of the changed file in the working tree`
|
||||
});
|
||||
}
|
||||
@@ -142,13 +142,13 @@ export class CommitDetailsQuickPick {
|
||||
items.splice(0, 0, goBackCommand);
|
||||
}
|
||||
|
||||
let previousCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>);
|
||||
let nextCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>);
|
||||
let previousCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>) | undefined = undefined;
|
||||
let nextCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>) | undefined = undefined;
|
||||
if (!stash) {
|
||||
// If we have the full history, we are good
|
||||
if (repoLog && !repoLog.truncated && !repoLog.sha) {
|
||||
previousCommand = commit.previousSha && new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [commit.previousUri, commit.previousSha, undefined, goBackCommand, repoLog]);
|
||||
nextCommand = commit.nextSha && new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [commit.nextUri, commit.nextSha, undefined, goBackCommand, repoLog]);
|
||||
previousCommand = commit.previousSha === undefined ? undefined : new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [commit.previousUri, commit.previousSha, undefined, goBackCommand, repoLog]);
|
||||
nextCommand = commit.nextSha === undefined ? undefined : new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [commit.nextUri, commit.nextSha, undefined, goBackCommand, repoLog]);
|
||||
}
|
||||
else {
|
||||
previousCommand = async () => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Arrays, Iterables } from '../system';
|
||||
import { QuickPickItem, QuickPickOptions, Uri, window } from 'vscode';
|
||||
import { Commands, Keyboard, KeyNoopCommand } from '../commands';
|
||||
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, KeyCommandQuickPickItem, OpenFileCommandQuickPickItem } from './common';
|
||||
import { GitLogCommit, GitService, GitUri, IGitLog } from '../gitService';
|
||||
import { GitBranch, GitLogCommit, GitService, GitUri, IGitLog } from '../gitService';
|
||||
import { OpenRemotesCommandQuickPickItem } from './remotes';
|
||||
import * as moment from 'moment';
|
||||
import * as path from 'path';
|
||||
@@ -14,7 +14,7 @@ export class OpenCommitFileCommandQuickPickItem extends OpenFileCommandQuickPick
|
||||
let description: string;
|
||||
let uri: Uri;
|
||||
if (commit.status === 'D') {
|
||||
uri = GitService.toGitContentUri(commit.previousSha, commit.previousShortSha, commit.previousFileName, commit.repoPath, undefined);
|
||||
uri = GitService.toGitContentUri(commit.previousSha!, commit.previousShortSha!, commit.previousFileName!, commit.repoPath, undefined);
|
||||
description = `\u00a0 \u2014 \u00a0\u00a0 ${path.basename(commit.fileName)} in \u00a0$(git-commit) ${commit.previousShortSha} (deleted in \u00a0$(git-commit) ${commit.shortSha})`;
|
||||
}
|
||||
else {
|
||||
@@ -51,8 +51,10 @@ export class CommitFileDetailsQuickPick {
|
||||
const isUncommitted = commit.isUncommitted;
|
||||
if (isUncommitted) {
|
||||
// Since we can't trust the previous sha on an uncommitted commit, find the last commit for this file
|
||||
commit = await git.getLogCommit(undefined, commit.uri.fsPath, { previous: true });
|
||||
if (!commit) return undefined;
|
||||
const c = await git.getLogCommit(undefined, commit.uri.fsPath, { previous: true });
|
||||
if (c === undefined) return undefined;
|
||||
|
||||
commit = c;
|
||||
}
|
||||
|
||||
if (!stash) {
|
||||
@@ -99,7 +101,7 @@ export class CommitFileDetailsQuickPick {
|
||||
items.push(new OpenRemotesCommandQuickPickItem(remotes, 'file', commit.fileName, undefined, commit, currentCommand));
|
||||
}
|
||||
if (commit.workingFileName && commit.status !== 'D') {
|
||||
const branch = await git.getBranch(commit.repoPath || git.repoPath);
|
||||
const branch = await git.getBranch(commit.repoPath || git.repoPath) as GitBranch;
|
||||
items.push(new OpenRemotesCommandQuickPickItem(remotes, 'working-file', commit.workingFileName, branch.name, undefined, currentCommand));
|
||||
}
|
||||
}
|
||||
@@ -122,13 +124,13 @@ export class CommitFileDetailsQuickPick {
|
||||
items.splice(0, 0, goBackCommand);
|
||||
}
|
||||
|
||||
let previousCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>);
|
||||
let nextCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>);
|
||||
let previousCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>) | undefined = undefined;
|
||||
let nextCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>) | undefined = undefined;
|
||||
if (!stash) {
|
||||
// If we have the full history, we are good
|
||||
if (fileLog && !fileLog.truncated && !fileLog.sha) {
|
||||
previousCommand = commit.previousSha && new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [commit.previousUri, commit.previousSha, undefined, goBackCommand, fileLog]);
|
||||
nextCommand = commit.nextSha && new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [commit.nextUri, commit.nextSha, undefined, goBackCommand, fileLog]);
|
||||
previousCommand = commit.previousSha === undefined ? undefined : new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [commit.previousUri, commit.previousSha, undefined, goBackCommand, fileLog]);
|
||||
nextCommand = commit.nextSha === undefined ? undefined : new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [commit.nextUri, commit.nextSha, undefined, goBackCommand, fileLog]);
|
||||
}
|
||||
else {
|
||||
previousCommand = async () => {
|
||||
@@ -138,6 +140,8 @@ export class CommitFileDetailsQuickPick {
|
||||
// If we can't find the commit or the previous commit isn't available (since it isn't trustworthy)
|
||||
if (!c || !c.previousSha) {
|
||||
log = await git.getLogForFile(commit.repoPath, uri.fsPath, commit.sha, git.config.advanced.maxQuickHistory);
|
||||
if (log === undefined) return KeyNoopCommand;
|
||||
|
||||
c = log && log.commits.get(commit.sha);
|
||||
// Since we exclude merge commits in file log, just grab the first returned commit
|
||||
if (!c && commit.isMerge) {
|
||||
|
||||
@@ -8,7 +8,8 @@ import { GitCommit, GitLogCommit, GitStashCommit } from '../gitService';
|
||||
import * as moment from 'moment';
|
||||
|
||||
export function getQuickPickIgnoreFocusOut() {
|
||||
return !workspace.getConfiguration(ExtensionKey).get<IAdvancedConfig>('advanced').quickPick.closeOnFocusOut;
|
||||
const cfg = workspace.getConfiguration(ExtensionKey).get<IAdvancedConfig>('advanced')!;
|
||||
return !cfg.quickPick.closeOnFocusOut;
|
||||
}
|
||||
|
||||
export function showQuickPickProgress(message: string, mapping?: KeyMapping, delay: boolean = false): CancellationTokenSource {
|
||||
@@ -32,7 +33,7 @@ export function showQuickPickProgress(message: string, mapping?: KeyMapping, del
|
||||
async function _showQuickPickProgress(message: string, cancellation: CancellationTokenSource, mapping?: KeyMapping) {
|
||||
// Logger.log(`showQuickPickProgress`, `show`, message);
|
||||
|
||||
const scope: KeyboardScope = mapping && await Keyboard.instance.beginScope(mapping);
|
||||
const scope: KeyboardScope | undefined = mapping && await Keyboard.instance.beginScope(mapping);
|
||||
|
||||
try {
|
||||
await window.showQuickPick(_getInfiniteCancellablePromise(cancellation), {
|
||||
@@ -64,21 +65,23 @@ export class CommandQuickPickItem implements QuickPickItem {
|
||||
|
||||
label: string;
|
||||
description: string;
|
||||
detail: string;
|
||||
detail?: string | undefined;
|
||||
|
||||
constructor(item: QuickPickItem, protected command: Commands, protected args?: any[]) {
|
||||
constructor(item: QuickPickItem, protected command: Commands | undefined, protected args?: any[]) {
|
||||
Object.assign(this, item);
|
||||
}
|
||||
|
||||
execute(): Thenable<{}> {
|
||||
execute(): Thenable<{} | undefined> {
|
||||
if (this.command === undefined) return Promise.resolve(undefined);
|
||||
|
||||
return commands.executeCommand(this.command, ...(this.args || []));
|
||||
}
|
||||
}
|
||||
|
||||
export class KeyCommandQuickPickItem extends CommandQuickPickItem {
|
||||
|
||||
constructor(protected command: Commands, protected args?: any[]) {
|
||||
super({ label: undefined, description: undefined }, command, args);
|
||||
constructor(command: Commands, args?: any[]) {
|
||||
super({ label: '', description: '' } as QuickPickItem, command, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +91,7 @@ export class OpenFileCommandQuickPickItem extends CommandQuickPickItem {
|
||||
super(item, undefined, undefined);
|
||||
}
|
||||
|
||||
async execute(pinned: boolean = false): Promise<{}> {
|
||||
async execute(pinned: boolean = false): Promise<{} | undefined> {
|
||||
return this.open(pinned);
|
||||
}
|
||||
|
||||
@@ -103,7 +106,7 @@ export class OpenFilesCommandQuickPickItem extends CommandQuickPickItem {
|
||||
super(item, undefined, undefined);
|
||||
}
|
||||
|
||||
async execute(): Promise<{}> {
|
||||
async execute(): Promise<{} | undefined> {
|
||||
for (const uri of this.uris) {
|
||||
await openEditor(uri, true);
|
||||
}
|
||||
@@ -126,7 +129,7 @@ export class CommitQuickPickItem implements QuickPickItem {
|
||||
|
||||
if (commit instanceof GitStashCommit) {
|
||||
this.label = `${commit.stashName}\u00a0\u2022\u00a0${message}`;
|
||||
this.description = null;
|
||||
this.description = '';
|
||||
this.detail = `\u00a0 ${moment(commit.date).fromNow()}\u00a0\u00a0\u2022\u00a0 ${commit.getDiffStatus()}`;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -21,7 +21,7 @@ export class FileHistoryQuickPick {
|
||||
static async show(git: GitService, log: IGitLog, uri: GitUri, progressCancellation: CancellationTokenSource, goBackCommand?: CommandQuickPickItem, nextPageCommand?: CommandQuickPickItem): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> {
|
||||
const items = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))) as (CommitQuickPickItem | CommandQuickPickItem)[];
|
||||
|
||||
let previousPageCommand: CommandQuickPickItem;
|
||||
let previousPageCommand: CommandQuickPickItem | undefined = undefined;
|
||||
|
||||
let index = 0;
|
||||
if (log.truncated || log.sha) {
|
||||
@@ -63,18 +63,19 @@ export class FileHistoryQuickPick {
|
||||
}, Commands.ShowQuickFileHistory, [uri, undefined, log.maxCount, goBackCommand, undefined, nextPageCommand]);
|
||||
|
||||
const last = Iterables.last(log.commits.values());
|
||||
if (last != null) {
|
||||
previousPageCommand = new CommandQuickPickItem({
|
||||
label: `$(arrow-left) Show Previous Commits`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 shows ${log.maxCount} older commits`
|
||||
}, Commands.ShowQuickFileHistory, [new GitUri(uri, last), undefined, log.maxCount, goBackCommand, undefined, npc]);
|
||||
|
||||
previousPageCommand = new CommandQuickPickItem({
|
||||
label: `$(arrow-left) Show Previous Commits`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 shows ${log.maxCount} older commits`
|
||||
}, Commands.ShowQuickFileHistory, [new GitUri(uri, last), undefined, log.maxCount, goBackCommand, undefined, npc]);
|
||||
|
||||
index++;
|
||||
items.splice(0, 0, previousPageCommand);
|
||||
index++;
|
||||
items.splice(0, 0, previousPageCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const branch = await git.getBranch(uri.repoPath);
|
||||
const branch = await git.getBranch(uri.repoPath!);
|
||||
|
||||
const currentCommand = new CommandQuickPickItem({
|
||||
label: `go back \u21A9`,
|
||||
@@ -85,7 +86,7 @@ export class FileHistoryQuickPick {
|
||||
if (!goBackCommand) {
|
||||
items.splice(index++, 0, new CommandQuickPickItem({
|
||||
label: `$(history) Show Branch History`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 shows \u00a0$(git-branch) ${branch.name} history`
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 shows \u00a0$(git-branch) ${branch!.name} history`
|
||||
}, Commands.ShowQuickCurrentBranchHistory,
|
||||
[
|
||||
undefined,
|
||||
@@ -93,9 +94,9 @@ export class FileHistoryQuickPick {
|
||||
]));
|
||||
}
|
||||
|
||||
const remotes = Arrays.uniqueBy(await git.getRemotes(uri.repoPath), _ => _.url, _ => !!_.provider);
|
||||
const remotes = Arrays.uniqueBy(await git.getRemotes(uri.repoPath!), _ => _.url, _ => !!_.provider);
|
||||
if (remotes.length) {
|
||||
items.splice(index++, 0, new OpenRemotesCommandQuickPickItem(remotes, 'file', uri.getRelativePath(), branch.name, uri.sha, currentCommand));
|
||||
items.splice(index++, 0, new OpenRemotesCommandQuickPickItem(remotes, 'file', uri.getRelativePath(), branch!.name, uri.sha, currentCommand));
|
||||
}
|
||||
|
||||
if (goBackCommand) {
|
||||
|
||||
@@ -12,8 +12,8 @@ export class OpenRemoteCommandQuickPickItem extends CommandQuickPickItem {
|
||||
|
||||
constructor(remote: GitRemote, type: RemoteOpenType, ...args: string[]) {
|
||||
super({
|
||||
label: `$(link-external) Open ${getNameFromRemoteOpenType(type)} in ${remote.provider.name}`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 $(repo) ${remote.provider.path}`
|
||||
label: `$(link-external) Open ${getNameFromRemoteOpenType(type)} in ${remote.provider!.name}`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 $(repo) ${remote.provider!.path}`
|
||||
}, undefined, undefined);
|
||||
|
||||
this.remote = remote;
|
||||
@@ -22,7 +22,7 @@ export class OpenRemoteCommandQuickPickItem extends CommandQuickPickItem {
|
||||
}
|
||||
|
||||
async execute(): Promise<{}> {
|
||||
return this.remote.provider.open(this.type, ...this.args);
|
||||
return this.remote.provider!.open(this.type, ...this.args!);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem {
|
||||
constructor(remotes: GitRemote[], type: 'file', fileName: string, branch?: string, commit?: GitLogCommit, goBackCommand?: CommandQuickPickItem);
|
||||
constructor(remotes: GitRemote[], type: 'file' | 'working-file', fileName: string, branch?: string, sha?: string, goBackCommand?: CommandQuickPickItem);
|
||||
constructor(remotes: GitRemote[], type: RemoteOpenType, branchOrShaOrFileName: string, goBackCommandOrFileBranch?: CommandQuickPickItem | string, fileShaOrCommit?: string | GitLogCommit, goBackCommand?: CommandQuickPickItem) {
|
||||
let fileBranch: string;
|
||||
let fileBranch: string | undefined = undefined;
|
||||
if (typeof goBackCommandOrFileBranch === 'string') {
|
||||
fileBranch = goBackCommandOrFileBranch;
|
||||
}
|
||||
@@ -43,9 +43,9 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem {
|
||||
|
||||
const name = getNameFromRemoteOpenType(type);
|
||||
|
||||
let fileSha: string;
|
||||
let description: string;
|
||||
let placeHolder: string;
|
||||
let fileSha: string | undefined = undefined;
|
||||
let description: string | undefined = undefined;
|
||||
let placeHolder: string | undefined = undefined;
|
||||
switch (type) {
|
||||
case 'branch':
|
||||
description = `$(git-branch) ${branchOrShaOrFileName}`;
|
||||
@@ -88,15 +88,15 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem {
|
||||
const remote = remotes[0];
|
||||
if (remotes.length === 1) {
|
||||
super({
|
||||
label: `$(link-external) Open ${name} in ${remote.provider.name}`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 $(repo) ${remote.provider.path} \u00a0\u2022\u00a0 ${description}`
|
||||
label: `$(link-external) Open ${name} in ${remote.provider!.name}`,
|
||||
description: `\u00a0 \u2014 \u00a0\u00a0 $(repo) ${remote.provider!.path} \u00a0\u2022\u00a0 ${description}`
|
||||
}, Commands.OpenInRemote, [undefined, remotes, type, [branchOrShaOrFileName, fileBranch, fileSha], goBackCommand]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const provider = remotes.every(_ => _.provider.name === remote.provider.name)
|
||||
? remote.provider.name
|
||||
const provider = remotes.every(_ => _.provider !== undefined && _.provider.name === remote.provider!.name)
|
||||
? remote.provider!.name
|
||||
: 'Remote';
|
||||
|
||||
super({
|
||||
|
||||
@@ -11,13 +11,13 @@ export class OpenStatusFileCommandQuickPickItem extends OpenFileCommandQuickPick
|
||||
constructor(status: GitStatusFile, item?: QuickPickItem) {
|
||||
const icon = status.getIcon();
|
||||
|
||||
let directory = GitService.normalizePath(path.dirname(status.fileName));
|
||||
let directory: string | undefined = GitService.normalizePath(path.dirname(status.fileName));
|
||||
if (!directory || directory === '.') {
|
||||
directory = undefined;
|
||||
directory = '';
|
||||
}
|
||||
|
||||
let description = (status.status === 'R' && status.originalFileName)
|
||||
? `${directory || ''} \u00a0\u2190\u00a0 ${status.originalFileName}`
|
||||
? `${directory} \u00a0\u2190\u00a0 ${status.originalFileName}`
|
||||
: directory;
|
||||
|
||||
super(status.Uri, item || {
|
||||
@@ -34,7 +34,7 @@ export class OpenStatusFilesCommandQuickPickItem extends CommandQuickPickItem {
|
||||
|
||||
super(item || {
|
||||
label: `$(file-symlink-file) Open Changed Files`,
|
||||
description: undefined
|
||||
description: ''
|
||||
//detail: `Opens all of the changed files in the repository`
|
||||
}, Commands.OpenChangedFiles, [undefined, uris]);
|
||||
}
|
||||
@@ -85,12 +85,12 @@ export class RepoStatusQuickPick {
|
||||
|
||||
items.splice(unstagedIndex, 0, new OpenStatusFilesCommandQuickPickItem(files.filter(_ => _.status !== 'D' && _.staged), {
|
||||
label: `\u00a0\u00a0\u00a0\u00a0 $(file-symlink-file) Open Staged Files`,
|
||||
description: undefined
|
||||
description: ''
|
||||
}));
|
||||
|
||||
items.push(new OpenStatusFilesCommandQuickPickItem(files.filter(_ => _.status !== 'D' && !_.staged), {
|
||||
label: `\u00a0\u00a0\u00a0\u00a0 $(file-symlink-file) Open Unstaged Files`,
|
||||
description: undefined
|
||||
description: ''
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -110,13 +110,13 @@ export class RepoStatusQuickPick {
|
||||
items.push(new OpenStatusFilesCommandQuickPickItem(files.filter(_ => _.status !== 'D')));
|
||||
items.push(new CommandQuickPickItem({
|
||||
label: '$(x) Close Unchanged Files',
|
||||
description: null
|
||||
description: ''
|
||||
}, Commands.CloseUnchangedFiles));
|
||||
}
|
||||
else {
|
||||
items.push(new CommandQuickPickItem({
|
||||
label: `No changes in the working tree`,
|
||||
description: null
|
||||
description: ''
|
||||
}, Commands.ShowQuickRepoStatus, [undefined, goBackCommand]));
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ export class RepoStatusQuickPick {
|
||||
if (status.upstream && !status.state.ahead && !status.state.behind) {
|
||||
items.splice(0, 0, new CommandQuickPickItem({
|
||||
label: `$(git-branch) ${status.branch} is up-to-date with \u00a0$(git-branch) ${status.upstream}`,
|
||||
description: null
|
||||
description: ''
|
||||
}, Commands.ShowQuickRepoStatus, [undefined, goBackCommand]));
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ export namespace Iterables {
|
||||
}
|
||||
}
|
||||
|
||||
export function find<T>(source: Iterable<T> | IterableIterator<T>, predicate: (item: T) => boolean): T {
|
||||
export function find<T>(source: Iterable<T> | IterableIterator<T>, predicate: (item: T) => boolean): T | null {
|
||||
for (const item of source) {
|
||||
if (predicate(item)) return item;
|
||||
}
|
||||
@@ -76,8 +76,8 @@ export namespace Iterables {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function last<T>(source: Iterable<T>): T {
|
||||
let item: T;
|
||||
export function last<T>(source: Iterable<T>): T | null {
|
||||
let item: T | null = null;
|
||||
for (item of source) { /* noop */ }
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class RenderWhitespaceConfiguration {
|
||||
return this.value != null && this.value !== 'none';
|
||||
}
|
||||
|
||||
get value(): string {
|
||||
get value(): string | undefined {
|
||||
return this.inspection.workspaceValue || this.inspection.globalValue || this.inspection.defaultValue;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ export class WhitespaceController extends Disposable {
|
||||
private _onConfigurationChanged() {
|
||||
if (this._disposed) return;
|
||||
|
||||
const inspection = workspace.getConfiguration('editor').inspect<string>('renderWhitespace');
|
||||
const inspection = workspace.getConfiguration('editor').inspect<string>('renderWhitespace')!;
|
||||
|
||||
if (!this._count) {
|
||||
this._configuration = new RenderWhitespaceConfiguration(inspection);
|
||||
@@ -125,8 +125,8 @@ export class WhitespaceController extends Disposable {
|
||||
|
||||
private async _overrideWhitespace() {
|
||||
Logger.log(`Override whitespace`);
|
||||
const config = workspace.getConfiguration('editor');
|
||||
return config.update('renderWhitespace', 'none', this._configuration.location === SettingLocation.global);
|
||||
const cfg = workspace.getConfiguration('editor');
|
||||
return cfg.update('renderWhitespace', 'none', this._configuration.location === SettingLocation.global);
|
||||
}
|
||||
|
||||
async restore() {
|
||||
@@ -142,8 +142,8 @@ export class WhitespaceController extends Disposable {
|
||||
|
||||
private async _restoreWhitespace() {
|
||||
Logger.log(`Restore whitespace`);
|
||||
const config = workspace.getConfiguration('editor');
|
||||
return config.update('renderWhitespace',
|
||||
const cfg = workspace.getConfiguration('editor');
|
||||
return cfg.update('renderWhitespace',
|
||||
this._configuration.location === SettingLocation.default
|
||||
? undefined
|
||||
: this._configuration.value,
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": [ "es6" ],
|
||||
"module": "commonjs",
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": false,
|
||||
"noUnusedLocals": true,
|
||||
"outDir": "out",
|
||||
"removeComments": true,
|
||||
"rootDir": ".",
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strictNullChecks": false,
|
||||
"strict": true,
|
||||
"target": "es6"
|
||||
},
|
||||
"exclude": [
|
||||
|
||||
Reference in New Issue
Block a user