mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-14 12:08:36 -05:00
Merge from vscode 1a81711a85e38ccf784110568ebf3784ab9094a5 (#9161)
* Merge from vscode 1a81711a85e38ccf784110568ebf3784ab9094a5 * small spacing fix
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
import { lstat, Stats } from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder } from 'vscode';
|
||||
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env } from 'vscode';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions } from './api/git';
|
||||
@@ -17,6 +17,7 @@ import { applyLineChanges, getModifiedRange, intersectDiffWithRange, invertLineC
|
||||
import { fromGitUri, toGitUri, isGitUri } from './uri';
|
||||
import { grep, isDescendant, pathEquals } from './util';
|
||||
import { Log, LogLevel } from './log';
|
||||
import { GitTimelineItem } from './timelineProvider';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -2331,23 +2332,47 @@ export class CommandCenter {
|
||||
return result && result.stash;
|
||||
}
|
||||
|
||||
@command('git.openDiff', { repository: false })
|
||||
async openDiff(uri: Uri, lhs: string, rhs: string) {
|
||||
@command('git.timeline.openDiff', { repository: false })
|
||||
async timelineOpenDiff(item: TimelineItem, uri: Uri | undefined, _source: string) {
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (uri == null || !GitTimelineItem.is(item)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const basename = path.basename(uri.fsPath);
|
||||
|
||||
let title;
|
||||
if ((lhs === 'HEAD' || lhs === '~') && rhs === '') {
|
||||
if ((item.previousRef === 'HEAD' || item.previousRef === '~') && item.ref === '') {
|
||||
title = `${basename} (Working Tree)`;
|
||||
}
|
||||
else if (lhs === 'HEAD' && rhs === '~') {
|
||||
else if (item.previousRef === 'HEAD' && item.ref === '~') {
|
||||
title = `${basename} (Index)`;
|
||||
} else {
|
||||
title = `${basename} (${lhs.endsWith('^') ? `${lhs.substr(0, 8)}^` : lhs.substr(0, 8)}) \u27f7 ${basename} (${rhs.endsWith('^') ? `${rhs.substr(0, 8)}^` : rhs.substr(0, 8)})`;
|
||||
title = `${basename} (${item.shortPreviousRef}) \u27f7 ${basename} (${item.shortRef})`;
|
||||
}
|
||||
|
||||
return commands.executeCommand('vscode.diff', toGitUri(uri, lhs), rhs === '' ? uri : toGitUri(uri, rhs), title);
|
||||
return commands.executeCommand('vscode.diff', toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title);
|
||||
}
|
||||
|
||||
@command('git.timeline.copyCommitId', { repository: false })
|
||||
async timelineCopyCommitId(item: TimelineItem, _uri: Uri | undefined, _source: string) {
|
||||
if (!GitTimelineItem.is(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
env.clipboard.writeText(item.ref);
|
||||
}
|
||||
|
||||
@command('git.timeline.copyCommitMessage', { repository: false })
|
||||
async timelineCopyCommitMessage(item: TimelineItem, _uri: Uri | undefined, _source: string) {
|
||||
if (!GitTimelineItem.is(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
env.clipboard.writeText(item.message);
|
||||
}
|
||||
|
||||
|
||||
private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any {
|
||||
const result = (...args: any[]) => {
|
||||
let result: Promise<any>;
|
||||
|
||||
@@ -5,19 +5,62 @@
|
||||
|
||||
import * as dayjs from 'dayjs';
|
||||
import * as advancedFormat from 'dayjs/plugin/advancedFormat';
|
||||
import * as relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import { CancellationToken, Disposable, Event, EventEmitter, ThemeIcon, TimelineItem, TimelineProvider, Uri, workspace, TimelineChangeEvent } from 'vscode';
|
||||
import { CancellationToken, Disposable, Event, EventEmitter, ThemeIcon, Timeline, TimelineChangeEvent, TimelineCursor, TimelineItem, TimelineProvider, Uri, workspace } from 'vscode';
|
||||
import { Model } from './model';
|
||||
import { Repository } from './repository';
|
||||
import { debounce } from './decorators';
|
||||
import { Status } from './api/git';
|
||||
|
||||
dayjs.extend(advancedFormat);
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
// TODO[ECA]: Localize all the strings
|
||||
// TODO[ECA]: Localize or use a setting for date format
|
||||
|
||||
export class GitTimelineItem extends TimelineItem {
|
||||
static is(item: TimelineItem): item is GitTimelineItem {
|
||||
return item instanceof GitTimelineItem;
|
||||
}
|
||||
|
||||
readonly ref: string;
|
||||
readonly previousRef: string;
|
||||
readonly message: string;
|
||||
|
||||
constructor(
|
||||
ref: string,
|
||||
previousRef: string,
|
||||
message: string,
|
||||
timestamp: number,
|
||||
id: string,
|
||||
contextValue: string
|
||||
) {
|
||||
const index = message.indexOf('\n');
|
||||
const label = index !== -1 ? `${message.substring(0, index)} \u2026` : message;
|
||||
|
||||
super(label, timestamp);
|
||||
|
||||
this.ref = ref;
|
||||
this.previousRef = previousRef;
|
||||
this.message = message;
|
||||
this.id = id;
|
||||
this.contextValue = contextValue;
|
||||
}
|
||||
|
||||
get shortRef() {
|
||||
return this.shortenRef(this.ref);
|
||||
}
|
||||
|
||||
get shortPreviousRef() {
|
||||
return this.shortenRef(this.previousRef);
|
||||
}
|
||||
|
||||
private shortenRef(ref: string): string {
|
||||
if (ref === '' || ref === '~' || ref === 'HEAD') {
|
||||
return ref;
|
||||
}
|
||||
return ref.endsWith('^') ? `${ref.substr(0, 8)}^` : ref.substr(0, 8);
|
||||
}
|
||||
}
|
||||
|
||||
export class GitTimelineProvider implements TimelineProvider {
|
||||
private _onDidChange = new EventEmitter<TimelineChangeEvent>();
|
||||
get onDidChange(): Event<TimelineChangeEvent> {
|
||||
@@ -44,7 +87,7 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
this._disposable.dispose();
|
||||
}
|
||||
|
||||
async provideTimeline(uri: Uri, _token: CancellationToken): Promise<TimelineItem[]> {
|
||||
async provideTimeline(uri: Uri, _cursor: TimelineCursor, _token: CancellationToken): Promise<Timeline> {
|
||||
// console.log(`GitTimelineProvider.provideTimeline: uri=${uri} state=${this._model.state}`);
|
||||
|
||||
const repo = this._model.getRepository(uri);
|
||||
@@ -53,7 +96,7 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
this._repoStatusDate = undefined;
|
||||
this._repo = undefined;
|
||||
|
||||
return [];
|
||||
return { items: [] };
|
||||
}
|
||||
|
||||
if (this._repo?.root !== repo.root) {
|
||||
@@ -72,25 +115,17 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
const commits = await repo.logFile(uri);
|
||||
|
||||
let dateFormatter: dayjs.Dayjs;
|
||||
const items = commits.map<TimelineItem>(c => {
|
||||
let message = c.message;
|
||||
|
||||
const index = message.indexOf('\n');
|
||||
if (index !== -1) {
|
||||
message = `${message.substring(0, index)} \u2026`;
|
||||
}
|
||||
|
||||
const items = commits.map<GitTimelineItem>(c => {
|
||||
dateFormatter = dayjs(c.authorDate);
|
||||
|
||||
const item = new TimelineItem(message, c.authorDate?.getTime() ?? 0);
|
||||
item.id = c.hash;
|
||||
const item = new GitTimelineItem(c.hash, `${c.hash}^`, c.message, c.authorDate?.getTime() ?? 0, c.hash, 'git:file:commit');
|
||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||
item.description = `${dateFormatter.fromNow()} \u2022 ${c.authorName}`;
|
||||
item.detail = `${c.authorName} (${c.authorEmail}) \u2014 ${c.hash.substr(0, 8)}\n${dateFormatter.fromNow()} (${dateFormatter.format('MMMM Do, YYYY h:mma')})\n\n${c.message}`;
|
||||
item.description = c.authorName;
|
||||
item.detail = `${c.authorName} (${c.authorEmail}) \u2014 ${c.hash.substr(0, 8)}\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n\n${c.message}`;
|
||||
item.command = {
|
||||
title: 'Open Diff',
|
||||
command: 'git.openDiff',
|
||||
arguments: [uri, `${c.hash}^`, c.hash]
|
||||
title: 'Open Comparison',
|
||||
command: 'git.timeline.openDiff',
|
||||
arguments: [uri, this.id, item]
|
||||
};
|
||||
|
||||
return item;
|
||||
@@ -123,16 +158,15 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
break;
|
||||
}
|
||||
|
||||
const item = new TimelineItem('Staged Changes', date.getTime());
|
||||
item.id = 'index';
|
||||
const item = new GitTimelineItem('~', 'HEAD', 'Staged Changes', date.getTime(), 'index', 'git:file:index');
|
||||
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
|
||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||
item.description = `${dateFormatter.fromNow()} \u2022 You`;
|
||||
item.detail = `You \u2014 Index\n${dateFormatter.fromNow()} (${dateFormatter.format('MMMM Do, YYYY h:mma')})\n${status}`;
|
||||
item.description = 'You';
|
||||
item.detail = `You \u2014 Index\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n${status}`;
|
||||
item.command = {
|
||||
title: 'Open Comparison',
|
||||
command: 'git.openDiff',
|
||||
arguments: [uri, 'HEAD', '~']
|
||||
command: 'git.timeline.openDiff',
|
||||
arguments: [uri, this.id, item]
|
||||
};
|
||||
|
||||
items.push(item);
|
||||
@@ -166,22 +200,21 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
break;
|
||||
}
|
||||
|
||||
const item = new TimelineItem('Uncommited Changes', date.getTime());
|
||||
item.id = 'working';
|
||||
const item = new GitTimelineItem('', index ? '~' : 'HEAD', 'Uncommited Changes', date.getTime(), 'working', 'git:file:working');
|
||||
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
|
||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||
item.description = `${dateFormatter.fromNow()} \u2022 You`;
|
||||
item.detail = `You \u2014 Working Tree\n${dateFormatter.fromNow()} (${dateFormatter.format('MMMM Do, YYYY h:mma')})\n${status}`;
|
||||
item.description = 'You';
|
||||
item.detail = `You \u2014 Working Tree\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n${status}`;
|
||||
item.command = {
|
||||
title: 'Open Comparison',
|
||||
command: 'git.openDiff',
|
||||
arguments: [uri, index ? '~' : 'HEAD', '']
|
||||
command: 'git.timeline.openDiff',
|
||||
arguments: [uri, this.id, item]
|
||||
};
|
||||
|
||||
items.push(item);
|
||||
}
|
||||
|
||||
return items;
|
||||
return { items: items };
|
||||
}
|
||||
|
||||
private onRepositoriesChanged(_repo: Repository) {
|
||||
@@ -208,6 +241,6 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
|
||||
@debounce(500)
|
||||
private fireChanged() {
|
||||
this._onDidChange.fire();
|
||||
this._onDidChange.fire({});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user