Skip to content

Commit

Permalink
#393 New extension setting to customise how Uncommitted Changes are d…
Browse files Browse the repository at this point in the history
…isplayed in the graph.
  • Loading branch information
mhutchie committed Oct 11, 2020
1 parent e18d7bb commit e799f69
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 13 deletions.
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,19 @@
"default": "rounded",
"description": "Specifies the style of the graph."
},
"git-graph.graph.uncommittedChanges": {
"type": "string",
"enum": [
"Open Circle at the Uncommitted Changes",
"Open Circle at the Checked Out Commit"
],
"enumDescriptions": [
"Display the Uncommitted Changes as a grey open circle, connected to the commit referenced by HEAD with a solid grey line. The current file system's state is therefore always displayed as an open circle.",
"Display the Uncommitted Changes as a grey closed circle, connected to the commit referenced by HEAD with a dotted grey line. The commit referenced by HEAD is therefore always displayed as an open circle."
],
"default": "Open Circle at the Uncommitted Changes",
"description": "Specifies how the Uncommitted Changes are displayed on the graph."
},
"git-graph.integratedTerminalShell": {
"type": "string",
"default": "",
Expand Down
6 changes: 5 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
GitResetMode,
GraphConfig,
GraphStyle,
GraphUncommittedChangesStyle,
MuteCommitsConfig,
OnRepoLoadConfig,
RefLabelAlignment,
Expand Down Expand Up @@ -261,7 +262,10 @@ class Config {
style: this.getRenamedExtensionSetting<string>('graph.style', 'graphStyle', 'rounded') === 'angular'
? GraphStyle.Angular
: GraphStyle.Rounded,
grid: { x: 16, y: 24, offsetX: 16, offsetY: 12, expandY: 250 }
grid: { x: 16, y: 24, offsetX: 16, offsetY: 12, expandY: 250 },
uncommittedChanges: this.config.get<string>('graph.uncommittedChanges', 'Open Circle at the Uncommitted Changes') === 'Open Circle at the Checked Out Commit'
? GraphUncommittedChangesStyle.OpenCircleAtTheCheckedOutCommit
: GraphUncommittedChangesStyle.OpenCircleAtTheUncommittedChanges
};
}

Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ export interface GraphConfig {
readonly colours: ReadonlyArray<string>;
readonly style: GraphStyle;
readonly grid: { x: number, y: number, offsetX: number, offsetY: number, expandY: number };
readonly uncommittedChanges: GraphUncommittedChangesStyle;
}

export type LoadGitGraphViewTo = {
Expand Down Expand Up @@ -449,6 +450,11 @@ export const enum GraphStyle {
Angular
}

export const enum GraphUncommittedChangesStyle {
OpenCircleAtTheUncommittedChanges,
OpenCircleAtTheCheckedOutCommit
}

export const enum IncludeCommitsMentionedByReflogs {
Default,
Enabled,
Expand Down
60 changes: 59 additions & 1 deletion tests/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vscode from './mocks/vscode';
jest.mock('vscode', () => vscode, { virtual: true });

import { getConfig } from '../src/config';
import { CommitDetailsViewLocation, CommitOrdering, DateFormatType, DateType, FileViewType, GitResetMode, GraphStyle, RepoDropdownOrder, SquashMessageFormat, TabIconColourTheme } from '../src/types';
import { CommitDetailsViewLocation, CommitOrdering, DateFormatType, DateType, FileViewType, GitResetMode, GraphStyle, GraphUncommittedChangesStyle, RepoDropdownOrder, SquashMessageFormat, TabIconColourTheme } from '../src/types';

let workspaceConfiguration = vscode.mocks.workspaceConfiguration;

Expand Down Expand Up @@ -1604,6 +1604,7 @@ describe('Config', () => {
const mockColoursExtensionSetting = (value: any) => {
vscode.mockRenamedExtensionSettingReturningValueOnce(value);
vscode.mockRenamedExtensionSettingReturningValueOnce(undefined);
workspaceConfiguration.get.mockImplementationOnce((_, defaultValue) => defaultValue);
};

it('Should return a filtered array of colours based on the configuration value', () => {
Expand Down Expand Up @@ -1662,6 +1663,7 @@ describe('Config', () => {
const mockStyleExtensionSetting = (value: any) => {
vscode.mockRenamedExtensionSettingReturningValueOnce(undefined);
vscode.mockRenamedExtensionSettingReturningValueOnce(value);
workspaceConfiguration.get.mockImplementationOnce((_, defaultValue) => defaultValue);
};

it('Should return GraphStyle.Rounded when the configuration value is "rounded"', () => {
Expand Down Expand Up @@ -1712,6 +1714,62 @@ describe('Config', () => {
expect(value).toBe(GraphStyle.Rounded);
});
});

describe('uncommittedChanges', () => {
const mockUncommittedChangesExtensionSetting = (value?: string) => {
vscode.mockRenamedExtensionSettingReturningValueOnce(undefined);
vscode.mockRenamedExtensionSettingReturningValueOnce(undefined);
workspaceConfiguration.get.mockImplementationOnce((_, defaultValue) => typeof value !== 'undefined' ? value : defaultValue);
};

it('Should return GraphUncommittedChangesStyle.OpenCircleAtTheUncommittedChanges when the configuration value is "Open Circle at the Uncommitted Changes"', () => {
// Setup
mockUncommittedChangesExtensionSetting('Open Circle at the Uncommitted Changes');

// Run
const value = config.graph.uncommittedChanges;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('graph.uncommittedChanges', 'Open Circle at the Uncommitted Changes');
expect(value).toBe(GraphUncommittedChangesStyle.OpenCircleAtTheUncommittedChanges);
});

it('Should return GraphUncommittedChangesStyle.OpenCircleAtTheCheckedOutCommit when the configuration value is "Open Circle at the Checked Out Commit"', () => {
// Setup
mockUncommittedChangesExtensionSetting('Open Circle at the Checked Out Commit');

// Run
const value = config.graph.uncommittedChanges;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('graph.uncommittedChanges', 'Open Circle at the Uncommitted Changes');
expect(value).toBe(GraphUncommittedChangesStyle.OpenCircleAtTheCheckedOutCommit);
});

it('Should return the default value (GraphUncommittedChangesStyle.OpenCircleAtTheUncommittedChanges) when the configuration value is invalid', () => {
// Setup
mockUncommittedChangesExtensionSetting('invalid');

// Run
const value = config.graph.uncommittedChanges;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('graph.uncommittedChanges', 'Open Circle at the Uncommitted Changes');
expect(value).toBe(GraphUncommittedChangesStyle.OpenCircleAtTheUncommittedChanges);
});

it('Should return the default value (GraphUncommittedChangesStyle.OpenCircleAtTheUncommittedChanges) when the configuration value is unknown', () => {
// Setup
mockUncommittedChangesExtensionSetting(undefined);

// Run
const value = config.graph.uncommittedChanges;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('graph.uncommittedChanges', 'Open Circle at the Uncommitted Changes');
expect(value).toBe(GraphUncommittedChangesStyle.OpenCircleAtTheUncommittedChanges);
});
});
});

describe('integratedTerminalShell', () => {
Expand Down
24 changes: 13 additions & 11 deletions web/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class Branch {
/* Rendering */

public draw(svg: SVGElement, config: GG.GraphConfig, expandAt: number) {
let colour = config.colours[this.colour % config.colours.length], i, x1, y1, x2, y2, lines: PlacedLine[] = [], curPath = '', curColour = '', d = config.grid.y * (config.style === GG.GraphStyle.Angular ? 0.38 : 0.8), line, nextLine;
let colour = config.colours[this.colour % config.colours.length], i, x1, y1, x2, y2, lines: PlacedLine[] = [], curPath = '', d = config.grid.y * (config.style === GG.GraphStyle.Angular ? 0.38 : 0.8), line, nextLine;

// Convert branch lines into pixel coordinates, respecting expanded commit extensions
for (i = 0; i < this.lines.length; i++) {
Expand Down Expand Up @@ -123,17 +123,13 @@ class Branch {

// If the new point belongs to a different path, render the current path and reset it for the new path
if (curPath !== '' && i > 0 && line.isCommitted !== lines[i - 1].isCommitted) {
this.drawPath(svg, curPath, curColour);
Branch.drawPath(svg, curPath, lines[i - 1].isCommitted, colour, config.uncommittedChanges);
curPath = '';
curColour = '';
}

// If the path hasn't been started or the new point belongs to a different path, move to p1
if (curPath === '' || (i > 0 && (x1 !== lines[i - 1].p2.x || y1 !== lines[i - 1].p2.y))) curPath += 'M' + x1.toFixed(0) + ',' + y1.toFixed(1);

// If the path hasn't been assigned a colour, assign it
if (curColour === '') curColour = line.isCommitted ? colour : '#808080';

if (x1 === x2) { // If the path is vertical, draw a straight line
curPath += 'L' + x2.toFixed(0) + ',' + y2.toFixed(1);
} else { // If the path moves horizontal, draw the appropriate transition
Expand All @@ -146,17 +142,20 @@ class Branch {
}

if (curPath !== '') {
this.drawPath(svg, curPath, curColour); // Draw the remaining path
Branch.drawPath(svg, curPath, lines[lines.length - 1].isCommitted, colour, config.uncommittedChanges); // Draw the remaining path
}
}

private drawPath(svg: SVGElement, path: string, colour: string) {
let shadow = svg.appendChild(document.createElementNS(SVG_NAMESPACE, 'path')), line = svg.appendChild(document.createElementNS(SVG_NAMESPACE, 'path'));
private static drawPath(svg: SVGElement, path: string, isCommitted: boolean, colour: string, uncommittedChanges: GG.GraphUncommittedChangesStyle) {
const shadow = svg.appendChild(document.createElementNS(SVG_NAMESPACE, 'path')), line = svg.appendChild(document.createElementNS(SVG_NAMESPACE, 'path'));
shadow.setAttribute('class', 'shadow');
shadow.setAttribute('d', path);
line.setAttribute('class', 'line');
line.setAttribute('d', path);
line.setAttribute('stroke', colour);
line.setAttribute('stroke', isCommitted ? colour : '#808080');
if (!isCommitted && uncommittedChanges === GG.GraphUncommittedChangesStyle.OpenCircleAtTheCheckedOutCommit) {
line.setAttribute('stroke-dasharray', '2px');
}
}
}

Expand Down Expand Up @@ -421,8 +420,11 @@ class Graph {
}

if (commits[0].hash === UNCOMMITTED) {
this.vertices[0].setCurrent();
this.vertices[0].setNotCommitted();
}

if (commits[0].hash === UNCOMMITTED && this.config.uncommittedChanges === GG.GraphUncommittedChangesStyle.OpenCircleAtTheUncommittedChanges) {
this.vertices[0].setCurrent();
} else if (commitHead !== null && typeof commitLookup[commitHead] === 'number') {
this.vertices[commitLookup[commitHead]].setCurrent();
}
Expand Down

0 comments on commit e799f69

Please sign in to comment.