diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58aa113..bcabefa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
## [8.3.0-beta] - 2018-05-05
### Added
+- Add user-defined modes for quickly toggling between sets of settings
+ - Adds *Switch Mode* command (`gitlens.switchMode`) to quickly switch the active mode
+ - Adds a built-in *Zen* mode which for a zen-like experience, disables many visual features
+ - Adds *Toggle Zen Mode* command (`gitlens.toggleZenMode`) to toggle Zen mode
+ - Adds a built-in *Review* mode which for reviewing code, enables many visual features
+ - Adds *Toggle Review Mode* command (`gitlens.toggleReviewMode`) to toggle Review mode
+ - Adds the active mode to the status bar, optional (on by default)
+ - Adds `gitlens.mode.statusBar.enabled` setting to specify whether to provide the active GitLens mode on the status bar
+ - Adds `gitlens.mode.statusBar.alignment` setting to specify the active GitLens mode alignment in the status bar
+ - Adds modes settings (`gitlens.mode.*`) to the interactive settings editor
+ ![modes settings](https://raw.githubusercontent.com/eamodio/vscode-gitlens/develop/images/cl-modes-settings.png)
+ - Adds `gitlens.mode.active` settings to specify the active GitLens mode, if any
+ - Adds `gitlens.modes` setting to specify the user-defined GitLens modes
- Adds an icon for the *Compare File with Previous Revision* command (`gitlens.diffWithPrevious`) and moves it into the editor toolbar
- Adds an icon for the *Compare File with Next Revision* command (`gitlens.diffWithNext`) and moves it into the editor toolbar
- Adds *Show GitLens Explorer* (`gitlens.showGitExplorer`) command — shows/expands the *GitLens* explorer
diff --git a/README.md b/README.md
index b508e0d..b599ffc 100644
--- a/README.md
+++ b/README.md
@@ -372,6 +372,16 @@ An on-demand, [customizable](#gitlens-results-view-settings "Jump to the GitLens
- Click the current and previous commit ids to execute the *Show Commit Details* command (`gitlens.showQuickCommitDetails`)
---
+### Modes
+- GitLens supports [user-defined](#modes-settings "Jump to the Modes settings") modes for quickly toggling between sets of settings
+ - Adds *Switch Mode* command (`gitlens.switchMode`) to quickly switch the active mode
+ - Adds a built-in *Zen* mode which for a zen-like experience, disables many visual features
+ - Adds *Toggle Zen Mode* command (`gitlens.toggleZenMode`) to toggle Zen mode
+ - Adds a built-in *Review* mode which for reviewing code, enables many visual features
+ - Adds *Toggle Review Mode* command (`gitlens.toggleReviewMode`) to toggle Review mode
+ - Adds the active mode to the **status bar** ([optional](#modes-settings "Jump to the Modes settings"), on by default)
+
+---
### Recent Changes
@@ -671,13 +681,22 @@ See also [Explorer Settings](#explorer-settings "Jump to the Explorer settings")
|`gitlens.hovers.annotations.changes`|Specifies whether to provide a changes (diff) hover for all lines when showing blame annotations
|`gitlens.hovers.annotations.details`|Specifies whether to provide a commit details hover for all lines when showing blame annotations
|`gitlens.hovers.annotations.enabled`|Specifies whether to provide any hovers when showing blame annotations
-|`gitlens.hovers.annotations.over`|Specifies when to trigger hovers when showing blame annotations `annotation` - only shown when hovering over the line annotation `line` - shown when hovering anywhere over the line
+|`gitlens.hovers.annotations.over`|Specifies when to trigger hovers when showing blame annotations `annotation` - only shown when hovering over the line annotation `line` - shown when hovering anywhere over the line
|`gitlens.hovers.currentLine.changes`|Specifies whether to provide a changes (diff) hover for the current line
|`gitlens.hovers.currentLine.details`|Specifies whether to provide a commit details hover for the current line
|`gitlens.hovers.currentLine.enabled`|Specifies whether to provide any hovers for the current line
-|`gitlens.hovers.currentLine.over`|Specifies when to trigger hovers for the current line `annotation` - only shown when hovering over the line annotation `line` - shown when hovering anywhere over the line
+|`gitlens.hovers.currentLine.over`|Specifies when to trigger hovers for the current line `annotation` - only shown when hovering over the line annotation `line` - shown when hovering anywhere over the line
|`gitlens.hovers.enabled`|Specifies whether to provide any hovers
+### Modes Settings
+
+|Name | Description
+|-----|------------
+|`gitlens.mode.active`|Specifies the active GitLens mode, if any
+|`gitlens.mode.statusBar.enabled`|Specifies whether to provide the active GitLens mode on the status bar
+|`gitlens.mode.statusBar.alignment`|Specifies the active GitLens mode alignment in the status bar `left` - align to the left `right` - align to the right
+|`gitlens.modes`|Specifies the user-defined GitLens modes
+
### Recent Changes Settings
|Name | Description
diff --git a/images/cl-modes-settings.png b/images/cl-modes-settings.png
new file mode 100644
index 0000000..4336558
Binary files /dev/null and b/images/cl-modes-settings.png differ
diff --git a/package.json b/package.json
index 4c826f7..344df86 100644
--- a/package.json
+++ b/package.json
@@ -670,6 +670,102 @@
"description": "Specifies which commands will be added to which menus",
"scope": "window"
},
+ "gitlens.mode.active": {
+ "type": "string",
+ "description": "Specifies the active GitLens mode, if any",
+ "scope": "window"
+ },
+ "gitlens.mode.statusBar.enabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Specifies whether to provide the active GitLens mode on the status bar",
+ "scope": "window"
+ },
+ "gitlens.mode.statusBar.alignment": {
+ "type": "string",
+ "default": "right",
+ "enum": [
+ "left",
+ "right"
+ ],
+ "description": "Specifies the active GitLens mode alignment in the status bar\n `left` - align to the left\n `right` - align to the right",
+ "scope": "window"
+ },
+ "gitlens.modes": {
+ "type": "object",
+ "properties": {
+ "zen": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": { "type": "string"},
+ "statusBarItemName": { "type": "string"},
+ "description": { "type": "string"},
+ "codeLens": { "type": "boolean" },
+ "currentLine": { "type": "boolean" },
+ "explorers": { "type": "boolean" },
+ "hovers": { "type": "boolean" },
+ "statusBar": { "type": "boolean" }
+ }
+ },
+ "review": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": { "type": "string"},
+ "statusBarItemName": { "type": "string"},
+ "description": { "type": "string"},
+ "codeLens": { "type": "boolean" },
+ "currentLine": { "type": "boolean" },
+ "explorers": { "type": "boolean" },
+ "hovers": { "type": "boolean" },
+ "statusBar": { "type": "boolean" }
+ }
+ }
+ },
+ "additionalProperties": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": { "type": "string"},
+ "statusBarItemName": { "type": "string"},
+ "description": { "type": "string"},
+ "codeLens": { "type": "boolean" },
+ "currentLine": { "type": "boolean" },
+ "explorers": { "type": "boolean" },
+ "hovers": { "type": "boolean" },
+ "statusBar": { "type": "boolean" }
+ }
+ },
+ "default": {
+ "zen": {
+ "name": "Zen",
+ "statusBarItemName": "Zen",
+ "description": "for a zen-like experience, disables many visual features",
+ "codeLens": false,
+ "currentLine": false,
+ "explorers": false,
+ "hovers": false,
+ "statusBar": false
+ },
+ "review": {
+ "name": "Review",
+ "statusBarItemName": "Reviewing",
+ "description": "for reviewing code, enables many visual features",
+ "codeLens": true,
+ "currentLine": true,
+ "hovers": true
+ }
+ },
+ "description": "Specifies the user-defined GitLens modes",
+ "scope": "window"
+ },
"gitlens.outputLevel": {
"type": "string",
"default": "silent",
@@ -1242,6 +1338,21 @@
"category": "GitLens"
},
{
+ "command": "gitlens.switchMode",
+ "title": "Switch Mode",
+ "category": "GitLens"
+ },
+ {
+ "command": "gitlens.toggleReviewMode",
+ "title": "Toggle Review Mode",
+ "category": "GitLens"
+ },
+ {
+ "command": "gitlens.toggleZenMode",
+ "title": "Toggle Zen Mode",
+ "category": "GitLens"
+ },
+ {
"command": "gitlens.showCommitSearch",
"title": "Search Commits",
"category": "GitLens",
@@ -1848,6 +1959,18 @@
"when": "gitlens:enabled && gitlens:canToggleCodeLens"
},
{
+ "command": "gitlens.switchMode",
+ "when": "gitlens:enabled"
+ },
+ {
+ "command": "gitlens.toggleReviewMode",
+ "when": "gitlens:enabled"
+ },
+ {
+ "command": "gitlens.toggleZenMode",
+ "when": "gitlens:enabled"
+ },
+ {
"command": "gitlens.showCommitSearch",
"when": "gitlens:enabled"
},
diff --git a/src/annotations/lineAnnotationController.ts b/src/annotations/lineAnnotationController.ts
index 846ff44..cc398b5 100644
--- a/src/annotations/lineAnnotationController.ts
+++ b/src/annotations/lineAnnotationController.ts
@@ -1,7 +1,7 @@
'use strict';
import { ConfigurationChangeEvent, debug, DecorationRangeBehavior, DecorationRenderOptions, Disposable, Range, TextEditor, TextEditorDecorationType, window } from 'vscode';
import { Annotations } from './annotations';
-import { configuration, IConfig } from './../configuration';
+import { configuration } from './../configuration';
import { isTextEditor, RangeEndOfLineIndex } from './../constants';
import { Container } from './../container';
import { LinesChangeEvent } from './../trackers/gitLineTracker';
@@ -47,8 +47,7 @@ export class LineAnnotationController extends Disposable {
if (!initializing && !configuration.changed(e, configuration.name('currentLine').value)) return;
if (initializing || configuration.changed(e, configuration.name('currentLine')('enabled').value)) {
- const cfg = configuration.get();
- if (cfg.currentLine.enabled) {
+ if (Container.config.currentLine.enabled) {
this._enabled = true;
this.resume();
}
diff --git a/src/annotations/lineHoverController.ts b/src/annotations/lineHoverController.ts
index 12a0826..3dd68ea 100644
--- a/src/annotations/lineHoverController.ts
+++ b/src/annotations/lineHoverController.ts
@@ -1,7 +1,7 @@
'use strict';
import { CancellationToken, ConfigurationChangeEvent, debug, Disposable, Hover, HoverProvider, languages, Position, Range, TextDocument, TextEditor, window } from 'vscode';
import { Annotations } from './annotations';
-import { configuration, IConfig } from './../configuration';
+import { configuration } from './../configuration';
import { RangeEndOfLineIndex } from './../constants';
import { Container } from './../container';
import { LinesChangeEvent } from './../trackers/gitLineTracker';
@@ -38,9 +38,7 @@ export class LineHoverController extends Disposable {
!configuration.changed(e, configuration.name('hovers')('enabled').value) &&
!configuration.changed(e, configuration.name('hovers')('currentLine')('enabled').value)) return;
- const cfg = configuration.get();
-
- if (cfg.hovers.enabled && cfg.hovers.currentLine.enabled) {
+ if (Container.config.hovers.enabled && Container.config.hovers.currentLine.enabled) {
Container.lineTracker.start(
this,
Disposable.from(Container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this))
diff --git a/src/codeLensController.ts b/src/codeLensController.ts
index 934b53a..b6e0397 100644
--- a/src/codeLensController.ts
+++ b/src/codeLensController.ts
@@ -1,6 +1,6 @@
'use strict';
import { ConfigurationChangeEvent, Disposable, languages } from 'vscode';
-import { configuration, ICodeLensConfig } from './configuration';
+import { configuration } from './configuration';
import { CommandContext, setCommandContext } from './constants';
import { Container } from './container';
import { DocumentBlameStateChangeEvent, DocumentDirtyIdleTriggerEvent, GitDocumentState } from './trackers/gitDocumentTracker';
@@ -39,7 +39,7 @@ export class CodeLensController extends Disposable {
Logger.log('CodeLens config changed; resetting CodeLens provider');
}
- const cfg = configuration.get(section);
+ const cfg = Container.config.codeLens;
if (cfg.enabled && (cfg.recentChange.enabled || cfg.authors.enabled)) {
if (this._provider !== undefined) {
this._provider.reset();
@@ -72,7 +72,7 @@ export class CodeLensController extends Disposable {
private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent) {
if (this._provider === undefined || !e.document.isBlameable) return;
- const maxLines = configuration.get(configuration.name('advanced')('blame')('sizeThresholdAfterEdit').value);
+ const maxLines = Container.config.advanced.blame.sizeThresholdAfterEdit;
if (maxLines > 0 && e.document.lineCount > maxLines) return;
Logger.log('Dirty idle triggered; resetting CodeLens provider');
diff --git a/src/commands.ts b/src/commands.ts
index f3d4384..a586990 100644
--- a/src/commands.ts
+++ b/src/commands.ts
@@ -44,6 +44,7 @@ export * from './commands/showResultsExplorer';
export * from './commands/stashApply';
export * from './commands/stashDelete';
export * from './commands/stashSave';
+export * from './commands/switchMode';
export * from './commands/toggleCodeLens';
export * from './commands/toggleFileBlame';
export * from './commands/toggleFileHeatmap';
@@ -95,9 +96,12 @@ export function configureCommands(): void {
Container.context.subscriptions.push(new Commands.StashApplyCommand());
Container.context.subscriptions.push(new Commands.StashDeleteCommand());
Container.context.subscriptions.push(new Commands.StashSaveCommand());
+ Container.context.subscriptions.push(new Commands.SwitchModeCommand());
Container.context.subscriptions.push(new Commands.ToggleCodeLensCommand());
Container.context.subscriptions.push(new Commands.ToggleFileBlameCommand());
Container.context.subscriptions.push(new Commands.ToggleFileHeatmapCommand());
Container.context.subscriptions.push(new Commands.ToggleFileRecentChangesCommand());
Container.context.subscriptions.push(new Commands.ToggleLineBlameCommand());
+ Container.context.subscriptions.push(new Commands.ToggleReviewModeCommand());
+ Container.context.subscriptions.push(new Commands.ToggleZenModeCommand());
}
\ No newline at end of file
diff --git a/src/commands/common.ts b/src/commands/common.ts
index d1b1282..b6be2ab 100644
--- a/src/commands/common.ts
+++ b/src/commands/common.ts
@@ -57,11 +57,14 @@ export enum Commands {
StashApply = 'gitlens.stashApply',
StashDelete = 'gitlens.stashDelete',
StashSave = 'gitlens.stashSave',
+ SwitchMode = 'gitlens.switchMode',
ToggleCodeLens = 'gitlens.toggleCodeLens',
ToggleFileBlame = 'gitlens.toggleFileBlame',
ToggleFileHeatmap = 'gitlens.toggleFileHeatmap',
ToggleFileRecentChanges = 'gitlens.toggleFileRecentChanges',
- ToggleLineBlame = 'gitlens.toggleLineBlame'
+ ToggleLineBlame = 'gitlens.toggleLineBlame',
+ ToggleReviewMode = 'gitlens.toggleReviewMode',
+ ToggleZenMode = 'gitlens.toggleZenMode'
}
export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined {
diff --git a/src/commands/switchMode.ts b/src/commands/switchMode.ts
new file mode 100644
index 0000000..81cc953
--- /dev/null
+++ b/src/commands/switchMode.ts
@@ -0,0 +1,48 @@
+'use strict';
+import { ConfigurationTarget } from 'vscode';
+import { Command, Commands } from './common';
+import { configuration } from '../configuration';
+import { Container } from '../container';
+import { ModesQuickPick } from '../quickPicks/quickPicks';
+
+export class SwitchModeCommand extends Command {
+
+ constructor() {
+ super(Commands.SwitchMode);
+ }
+
+ async execute() {
+ const pick = await ModesQuickPick.show();
+ if (pick === undefined) return;
+
+ await configuration.update(configuration.name('mode')('active').value, pick.key, ConfigurationTarget.Global);
+ }
+}
+
+export class ToggleReviewModeCommand extends Command {
+
+ constructor() {
+ super(Commands.ToggleReviewMode);
+ }
+
+ async execute() {
+ if (!Object.keys(Container.config.modes).includes('review')) return;
+
+ const mode = Container.config.mode.active === 'review' ? undefined : 'review';
+ await configuration.update(configuration.name('mode')('active').value, mode, ConfigurationTarget.Global);
+ }
+}
+
+export class ToggleZenModeCommand extends Command {
+
+ constructor() {
+ super(Commands.ToggleZenMode);
+ }
+
+ async execute() {
+ if (!Object.keys(Container.config.modes).includes('zen')) return;
+
+ const mode = Container.config.mode.active === 'zen' ? undefined : 'zen';
+ await configuration.update(configuration.name('mode')('active').value, mode, ConfigurationTarget.Global);
+ }
+}
diff --git a/src/configuration.ts b/src/configuration.ts
index f0e71d5..aec833f 100644
--- a/src/configuration.ts
+++ b/src/configuration.ts
@@ -26,6 +26,21 @@ export class Configuration {
return this._onDidChange.event;
}
+ private readonly _configAffectedByMode: string[];
+
+ constructor() {
+ this._configAffectedByMode = [
+ `gitlens.${this.name('mode').value}`,
+ `gitlens.${this.name('modes').value}`,
+ `gitlens.${this.name('codeLens').value}`,
+ `gitlens.${this.name('currentLine').value}`,
+ `gitlens.${this.name('gitExplorer').value}`,
+ `gitlens.${this.name('historyExplorer').value}`,
+ `gitlens.${this.name('hovers').value}`,
+ `gitlens.${this.name('statusBar').value}`
+ ];
+ }
+
private onConfigurationChanged(e: ConfigurationChangeEvent) {
if (!e.affectsConfiguration(ExtensionKey, null!)) return;
@@ -40,6 +55,21 @@ export class Configuration {
setCommandContext(CommandContext.KeyMap, this.get(section));
}
+ if (configuration.changed(e, configuration.name('mode').value) ||
+ configuration.changed(e, configuration.name('modes').value)) {
+ const original = e.affectsConfiguration;
+ e = {
+ ...e,
+ affectsConfiguration: (section: string, resource?: Uri) => {
+ if (this._configAffectedByMode.some(n => section.startsWith(n))) {
+ return true;
+ }
+
+ return original(section, resource);
+ }
+ } as ConfigurationChangeEvent;
+ }
+
this._onDidChange.fire(e);
}
@@ -186,4 +216,4 @@ export class Configuration {
}
}
-export const configuration = new Configuration();
\ No newline at end of file
+export const configuration = new Configuration();
diff --git a/src/container.ts b/src/container.ts
index 6efb407..c700b56 100644
--- a/src/container.ts
+++ b/src/container.ts
@@ -23,7 +23,7 @@ export class Container {
static initialize(context: ExtensionContext, config: IConfig) {
this._context = context;
- this._config = config;
+ this._config = Container.applyMode(config);
context.subscriptions.push(this._lineTracker = new GitLineTracker());
context.subscriptions.push(this._tracker = new GitDocumentTracker());
@@ -79,7 +79,7 @@ export class Container {
private static _config: IConfig | undefined;
static get config() {
if (this._config === undefined) {
- this._config = configuration.get();
+ this._config = Container.applyMode(configuration.get());
}
return this._config;
}
@@ -173,4 +173,32 @@ export class Container {
static resetConfig() {
this._config = undefined;
}
+
+ private static applyMode(config: IConfig) {
+ if (!config.mode.active) return config;
+
+ const mode = config.modes[config.mode.active];
+ if (mode == null) return config;
+
+ if (mode.codeLens != null) {
+ config.codeLens.enabled = mode.codeLens;
+ }
+ if (mode.currentLine != null) {
+ config.currentLine.enabled = mode.currentLine;
+ }
+ if (mode.explorers != null) {
+ config.gitExplorer.enabled = mode.explorers;
+ }
+ if (mode.explorers != null) {
+ config.historyExplorer.enabled = mode.explorers;
+ }
+ if (mode.hovers != null) {
+ config.hovers.enabled = mode.hovers;
+ }
+ if (mode.statusBar != null) {
+ config.statusBar.enabled = mode.statusBar;
+ }
+
+ return config;
+ }
}
diff --git a/src/gitCodeLensProvider.ts b/src/gitCodeLensProvider.ts
index 54f86ae..a91dd88 100644
--- a/src/gitCodeLensProvider.ts
+++ b/src/gitCodeLensProvider.ts
@@ -75,7 +75,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
if (document.isDirty) {
// Only allow dirty blames if we are idle
if (trackedDocument.isDirtyIdle) {
- const maxLines = configuration.get(configuration.name('advanced')('blame')('sizeThresholdAfterEdit').value);
+ const maxLines = Container.config.advanced.blame.sizeThresholdAfterEdit;
if (maxLines > 0 && document.lineCount > maxLines) {
dirty = true;
}
@@ -433,14 +433,8 @@ export class GitCodeLensProvider implements CodeLensProvider {
}
private getDirtyTitle(cfg: ICodeLensConfig) {
- if (cfg.recentChange.enabled && cfg.authors.enabled) {
- return configuration.get(configuration.name('strings')('codeLens')('unsavedChanges')('recentChangeAndAuthors').value);
- }
- else if (cfg.recentChange.enabled) {
- return configuration.get(configuration.name('strings')('codeLens')('unsavedChanges')('recentChangeOnly').value);
- }
- else {
- return configuration.get(configuration.name('strings')('codeLens')('unsavedChanges')('authorsOnly').value);
- }
+ if (cfg.recentChange.enabled && cfg.authors.enabled) return Container.config.strings.codeLens.unsavedChanges.recentChangeAndAuthors;
+ if (cfg.recentChange.enabled) return Container.config.strings.codeLens.unsavedChanges.recentChangeOnly;
+ return Container.config.strings.codeLens.unsavedChanges.authorsOnly;
}
}
\ No newline at end of file
diff --git a/src/quickPicks/modesQuickPick.ts b/src/quickPicks/modesQuickPick.ts
new file mode 100644
index 0000000..8595ae8
--- /dev/null
+++ b/src/quickPicks/modesQuickPick.ts
@@ -0,0 +1,40 @@
+'use strict';
+import { QuickPickItem, QuickPickOptions, window } from 'vscode';
+import { Container } from '../container';
+import { GlyphChars } from '../constants';
+
+export interface ModesQuickPickItem extends QuickPickItem {
+ key: string | undefined;
+}
+
+export class ModesQuickPick {
+
+ static async show(): Promise {
+ const modes = Object.keys(Container.config.modes);
+ if (modes.length === 0) return undefined;
+
+ const mode = Container.config.mode.active;
+
+ const items = modes.map(key => {
+ const modeCfg = Container.config.modes[key];
+ return {
+ label: `${mode === key ? '$(check)\u00a0\u00a0' : '\u00a0\u00a0\u00a0\u00a0\u00a0'}${modeCfg.name} mode`,
+ description: modeCfg.description ? `\u00a0${GlyphChars.Dash}\u00a0 ${modeCfg.description}` : '',
+ key: key
+ } as ModesQuickPickItem;
+ });
+
+ if (mode) {
+ items.splice(0, 0, {
+ label: `Exit ${Container.config.modes[mode].name} mode`,
+ key: undefined
+ } as ModesQuickPickItem);
+ }
+
+ const pick = await window.showQuickPick(items, {
+ placeHolder: 'select a GitLens mode to enter'
+ } as QuickPickOptions);
+
+ return pick;
+ }
+}
\ No newline at end of file
diff --git a/src/quickPicks/quickPicks.ts b/src/quickPicks/quickPicks.ts
index db0e185..faee378 100644
--- a/src/quickPicks/quickPicks.ts
+++ b/src/quickPicks/quickPicks.ts
@@ -8,6 +8,7 @@ export * from './commitQuickPick';
export * from './commitsQuickPick';
export * from './commonQuickPicks';
export * from './fileHistoryQuickPick';
+export * from './modesQuickPick';
export * from './remotesQuickPick';
export * from './repositoriesQuickPick';
export * from './repoStatusQuickPick';
diff --git a/src/statusBarController.ts b/src/statusBarController.ts
index 5098cd9..869afee 100644
--- a/src/statusBarController.ts
+++ b/src/statusBarController.ts
@@ -1,7 +1,7 @@
'use strict';
import { ConfigurationChangeEvent, Disposable, StatusBarAlignment, StatusBarItem, TextEditor, window } from 'vscode';
import { Commands } from './commands';
-import { configuration, IConfig, StatusBarCommand } from './configuration';
+import { configuration, StatusBarCommand } from './configuration';
import { isTextEditor } from './constants';
import { Container } from './container';
import { LinesChangeEvent } from './trackers/gitLineTracker';
@@ -9,8 +9,9 @@ import { CommitFormatter, GitCommit, ICommitFormatOptions } from './gitService';
export class StatusBarController extends Disposable {
+ private _blameStatusBarItem: StatusBarItem | undefined;
private _disposable: Disposable;
- private _statusBarItem: StatusBarItem | undefined;
+ private _modeStatusBarItem: StatusBarItem | undefined;
constructor() {
super(() => this.dispose());
@@ -22,9 +23,10 @@ export class StatusBarController extends Disposable {
}
dispose() {
- this.clear();
+ this.clearBlame();
- this._statusBarItem && this._statusBarItem.dispose();
+ this._blameStatusBarItem && this._blameStatusBarItem.dispose();
+ this._modeStatusBarItem && this._modeStatusBarItem.dispose();
Container.lineTracker.stop(this);
this._disposable && this._disposable.dispose();
@@ -33,21 +35,48 @@ export class StatusBarController extends Disposable {
private onConfigurationChanged(e: ConfigurationChangeEvent) {
const initializing = configuration.initializing(e);
+ if (initializing || configuration.changed(e, configuration.name('mode').value)) {
+ const mode = Container.config.mode.active && Container.config.mode.statusBar.enabled
+ ? Container.config.modes[Container.config.mode.active]
+ : undefined;
+ if (mode && mode.statusBarItemName) {
+ const alignment = Container.config.mode.statusBar.alignment !== 'left' ? StatusBarAlignment.Right : StatusBarAlignment.Left;
+
+ if (configuration.changed(e, configuration.name('mode')('statusBar')('alignment').value)) {
+ if (this._modeStatusBarItem !== undefined && this._modeStatusBarItem.alignment !== alignment) {
+ this._modeStatusBarItem.dispose();
+ this._modeStatusBarItem = undefined;
+ }
+ }
+
+ this._modeStatusBarItem = this._modeStatusBarItem || window.createStatusBarItem(alignment, alignment === StatusBarAlignment.Right ? 999 : 1);
+ this._modeStatusBarItem.command = Commands.SwitchMode;
+ this._modeStatusBarItem.text = mode.statusBarItemName;
+ this._modeStatusBarItem.tooltip = `Switch GitLens Mode`;
+ this._modeStatusBarItem.show();
+ }
+ else {
+ if (this._modeStatusBarItem !== undefined) {
+ this._modeStatusBarItem.dispose();
+ this._modeStatusBarItem = undefined;
+ }
+ }
+ }
+
if (!initializing && !configuration.changed(e, configuration.name('statusBar').value)) return;
- const cfg = configuration.get();
- if (cfg.statusBar.enabled) {
- const alignment = cfg.statusBar.alignment !== 'left' ? StatusBarAlignment.Right : StatusBarAlignment.Left;
+ if (Container.config.statusBar.enabled) {
+ const alignment = Container.config.statusBar.alignment !== 'left' ? StatusBarAlignment.Right : StatusBarAlignment.Left;
if (configuration.changed(e, configuration.name('statusBar')('alignment').value)) {
- if (this._statusBarItem !== undefined && this._statusBarItem.alignment !== alignment) {
- this._statusBarItem.dispose();
- this._statusBarItem = undefined;
+ if (this._blameStatusBarItem !== undefined && this._blameStatusBarItem.alignment !== alignment) {
+ this._blameStatusBarItem.dispose();
+ this._blameStatusBarItem = undefined;
}
}
- this._statusBarItem = this._statusBarItem || window.createStatusBarItem(alignment, alignment === StatusBarAlignment.Right ? 1000 : 0);
- this._statusBarItem.command = cfg.statusBar.command;
+ this._blameStatusBarItem = this._blameStatusBarItem || window.createStatusBarItem(alignment, alignment === StatusBarAlignment.Right ? 1000 : 0);
+ this._blameStatusBarItem.command = Container.config.statusBar.command;
if (initializing || configuration.changed(e, configuration.name('statusBar')('enabled').value)) {
Container.lineTracker.start(
@@ -60,9 +89,9 @@ export class StatusBarController extends Disposable {
if (configuration.changed(e, configuration.name('statusBar')('enabled').value)) {
Container.lineTracker.stop(this);
- if (this._statusBarItem !== undefined) {
- this._statusBarItem.dispose();
- this._statusBarItem = undefined;
+ if (this._blameStatusBarItem !== undefined) {
+ this._blameStatusBarItem.dispose();
+ this._blameStatusBarItem = undefined;
}
}
}
@@ -74,7 +103,7 @@ export class StatusBarController extends Disposable {
if (!e.pending && e.lines !== undefined) {
const state = Container.lineTracker.getState(e.lines[0]);
if (state !== undefined && state.commit !== undefined) {
- this.updateStatusBar(state.commit, e.editor!);
+ this.updateBlame(state.commit, e.editor!);
return;
}
@@ -83,54 +112,54 @@ export class StatusBarController extends Disposable {
}
if (clear) {
- this.clear();
+ this.clearBlame();
}
}
- async clear() {
- if (this._statusBarItem !== undefined) {
- this._statusBarItem.hide();
+ async clearBlame() {
+ if (this._blameStatusBarItem !== undefined) {
+ this._blameStatusBarItem.hide();
}
}
- private updateStatusBar(commit: GitCommit, editor: TextEditor) {
+ private updateBlame(commit: GitCommit, editor: TextEditor) {
const cfg = Container.config.statusBar;
- if (!cfg.enabled || this._statusBarItem === undefined || !isTextEditor(editor)) return;
+ if (!cfg.enabled || this._blameStatusBarItem === undefined || !isTextEditor(editor)) return;
- this._statusBarItem.text = `$(git-commit) ${CommitFormatter.fromTemplate(cfg.format, commit, {
+ this._blameStatusBarItem.text = `$(git-commit) ${CommitFormatter.fromTemplate(cfg.format, commit, {
truncateMessageAtNewLine: true,
dateFormat: cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat
} as ICommitFormatOptions)}`;
switch (cfg.command) {
case StatusBarCommand.ToggleFileBlame:
- this._statusBarItem.tooltip = 'Toggle Blame Annotations';
+ this._blameStatusBarItem.tooltip = 'Toggle Blame Annotations';
break;
case StatusBarCommand.DiffWithPrevious:
- this._statusBarItem.command = Commands.DiffLineWithPrevious;
- this._statusBarItem.tooltip = 'Compare Line Revision with Previous';
+ this._blameStatusBarItem.command = Commands.DiffLineWithPrevious;
+ this._blameStatusBarItem.tooltip = 'Compare Line Revision with Previous';
break;
case StatusBarCommand.DiffWithWorking:
- this._statusBarItem.command = Commands.DiffLineWithWorking;
- this._statusBarItem.tooltip = 'Compare Line Revision with Working';
+ this._blameStatusBarItem.command = Commands.DiffLineWithWorking;
+ this._blameStatusBarItem.tooltip = 'Compare Line Revision with Working';
break;
case StatusBarCommand.ToggleCodeLens:
- this._statusBarItem.tooltip = 'Toggle Git CodeLens';
+ this._blameStatusBarItem.tooltip = 'Toggle Git CodeLens';
break;
case StatusBarCommand.ShowQuickCommitDetails:
- this._statusBarItem.tooltip = 'Show Commit Details';
+ this._blameStatusBarItem.tooltip = 'Show Commit Details';
break;
case StatusBarCommand.ShowQuickCommitFileDetails:
- this._statusBarItem.tooltip = 'Show Line Commit Details';
+ this._blameStatusBarItem.tooltip = 'Show Line Commit Details';
break;
case StatusBarCommand.ShowQuickFileHistory:
- this._statusBarItem.tooltip = 'Show File History';
+ this._blameStatusBarItem.tooltip = 'Show File History';
break;
case StatusBarCommand.ShowQuickCurrentBranchHistory:
- this._statusBarItem.tooltip = 'Show Branch History';
+ this._blameStatusBarItem.tooltip = 'Show Branch History';
break;
}
- this._statusBarItem.show();
+ this._blameStatusBarItem.show();
}
}
\ No newline at end of file
diff --git a/src/ui/config.ts b/src/ui/config.ts
index a7caf76..eaee284 100644
--- a/src/ui/config.ts
+++ b/src/ui/config.ts
@@ -223,6 +223,17 @@ export interface IMenuConfig {
};
}
+export interface IModeConfig {
+ name: string;
+ statusBarItemName?: string;
+ description?: string;
+ codeLens?: boolean;
+ currentLine?: boolean;
+ explorers?: boolean;
+ hovers?: boolean;
+ statusBar?: boolean;
+}
+
export interface IResultsExplorerConfig {
files: IExplorersFilesConfig;
}
@@ -311,12 +322,20 @@ export interface IConfig {
insiders: boolean;
keymap: KeyMap;
menus: boolean | IMenuConfig;
+ mode: {
+ active: string;
+ statusBar: {
+ enabled: boolean;
+ alignment: 'left' | 'right';
+ }
+ };
+ modes: { [key: string]: IModeConfig };
outputLevel: OutputLevel;
recentChanges: {
highlight: {
locations: HighlightLocations[];
- };
+ }
toggleMode: AnnotationsToggleMode;
};
@@ -341,8 +360,8 @@ export interface IConfig {
recentChangeAndAuthors: string;
recentChangeOnly: string;
authorsOnly: string;
- };
- };
+ }
+ }
};
advanced: IAdvancedConfig;
diff --git a/src/ui/images/settings/modes-status-bar-left.png b/src/ui/images/settings/modes-status-bar-left.png
new file mode 100644
index 0000000..d766a04
Binary files /dev/null and b/src/ui/images/settings/modes-status-bar-left.png differ
diff --git a/src/ui/images/settings/modes-status-bar-right.png b/src/ui/images/settings/modes-status-bar-right.png
new file mode 100644
index 0000000..4e6464e
Binary files /dev/null and b/src/ui/images/settings/modes-status-bar-right.png differ
diff --git a/src/ui/settings/index.html b/src/ui/settings/index.html
index 1366a59..f1a3b34 100644
--- a/src/ui/settings/index.html
+++ b/src/ui/settings/index.html
@@ -829,6 +829,57 @@
+
+
diff --git a/src/views/historyExplorer.ts b/src/views/historyExplorer.ts
index 859b5f2..4330c60 100644
--- a/src/views/historyExplorer.ts
+++ b/src/views/historyExplorer.ts
@@ -57,10 +57,10 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider {
getBootstrap() {
return {
- config: Container.config,
+ // Make sure to get the raw config, not from the container which has the modes mixed in
+ config: configuration.get(),
scope: 'user',
scopes: this.getAvailableScopes()
} as SettingsBootstrap;
diff --git a/src/webviews/webviewEditor.ts b/src/webviews/webviewEditor.ts
index 2ae7546..b350cce 100644
--- a/src/webviews/webviewEditor.ts
+++ b/src/webviews/webviewEditor.ts
@@ -1,6 +1,6 @@
'use strict';
import { ConfigurationChangeEvent, ConfigurationTarget, Disposable, Uri, ViewColumn, WebviewPanel, WebviewPanelOnDidChangeViewStateEvent, window, workspace } from 'vscode';
-import { configuration } from '../configuration';
+import { configuration, IConfig } from '../configuration';
import { Container } from '../container';
import { Message, SettingsChangedMessage } from '../ui/ipc';
import { Logger } from '../logger';
@@ -162,6 +162,7 @@ export abstract class WebviewEditor extends Disposable {
}
private postUpdatedConfiguration() {
- return this.postMessage({ type: 'settingsChanged', config: Container.config } as SettingsChangedMessage, 'config');
+ // Make sure to get the raw config, not from the container which has the modes mixed in
+ return this.postMessage({ type: 'settingsChanged', config: configuration.get() } as SettingsChangedMessage, 'config');
}
}