Parcourir la source

Refines rebase editor

Adds button to rebase editor to toggle it on/off
Adds commands to toggle rebase editor on/off
Adds settings UI to toggle rebase editor on/off
main
Eric Amodio il y a 4 ans
Parent
révision
913c0606d0
19 fichiers modifiés avec 407 ajouts et 36 suppressions
  1. +21
    -1
      package.json
  2. +1
    -0
      src/commands.ts
  3. +2
    -0
      src/commands/common.ts
  4. +25
    -0
      src/commands/rebaseEditor.ts
  5. +6
    -4
      src/configuration.ts
  6. +10
    -1
      src/container.ts
  7. BIN
      src/webviews/apps/images/settings/rebase-editor.png
  8. +5
    -2
      src/webviews/apps/rebase/rebase.html
  9. +12
    -0
      src/webviews/apps/rebase/rebase.ts
  10. +61
    -0
      src/webviews/apps/scss/buttons.scss
  11. +15
    -3
      src/webviews/apps/scss/rebase.scss
  12. +39
    -0
      src/webviews/apps/settings/partials/rebase-editor.html
  13. +12
    -0
      src/webviews/apps/settings/settings.html
  14. +16
    -1
      src/webviews/apps/shared/appWithConfigBase.ts
  15. +4
    -0
      src/webviews/apps/shared/theme.ts
  16. +10
    -6
      src/webviews/protocol.ts
  17. +98
    -16
      src/webviews/rebaseEditor.ts
  18. +1
    -0
      src/webviews/settingsWebview.ts
  19. +69
    -2
      src/webviews/webviewBase.ts

+ 21
- 1
package.json Voir le fichier

@ -104,6 +104,8 @@
"onCommand:gitlens.diffWithWorkingInDiffLeft",
"onCommand:gitlens.diffWithWorkingInDiffRight",
"onCommand:gitlens.diffLineWithWorking",
"onCommand:gitlens.disableRebaseEditor",
"onCommand:gitlens.enableRebaseEditor",
"onCommand:gitlens.toggleFileBlame",
"onCommand:gitlens.toggleFileBlameInDiffLeft",
"onCommand:gitlens.toggleFileBlameInDiffRight",
@ -2759,6 +2761,16 @@
"category": "GitLens"
},
{
"command": "gitlens.disableRebaseEditor",
"title": "Disable Interactive Rebase Editor",
"category": "GitLens"
},
{
"command": "gitlens.enableRebaseEditor",
"title": "Enable Interactive Rebase Editor",
"category": "GitLens"
},
{
"command": "gitlens.toggleFileBlame",
"title": "Toggle File Blame",
"category": "GitLens",
@ -4527,6 +4539,14 @@
"when": "gitlens:activeFileStatus =~ /blameable/"
},
{
"command": "gitlens.disableRebaseEditor",
"when": "gitlens:enabled"
},
{
"command": "gitlens.enableRebaseEditor",
"when": "gitlens:enabled"
},
{
"command": "gitlens.externalDiff",
"when": "gitlens:activeFileStatus =~ /tracked/"
},
@ -7919,7 +7939,7 @@
"customEditors": [
{
"viewType": "gitlens.rebase",
"displayName": "Interactive Rebase Editor",
"displayName": "GitLens Interactive Rebase Editor",
"selector": [
{
"filenamePattern": "git-rebase-todo"

+ 1
- 0
src/commands.ts Voir le fichier

@ -34,6 +34,7 @@ export * from './commands/openPullRequestOnRemote';
export * from './commands/openRepoOnRemote';
export * from './commands/openRevisionFile';
export * from './commands/openWorkingFile';
export * from './commands/rebaseEditor';
export * from './commands/refreshHover';
export * from './commands/remoteProviders';
export * from './commands/repositories';

+ 2
- 0
src/commands/common.ts Voir le fichier

@ -63,6 +63,8 @@ export enum Commands {
DiffWithWorkingInDiffRight = 'gitlens.diffWithWorkingInDiffRight',
DiffLineWithWorking = 'gitlens.diffLineWithWorking',
DisconnectRemoteProvider = 'gitlens.disconnectRemoteProvider',
DisableRebaseEditor = 'gitlens.disableRebaseEditor',
EnableRebaseEditor = 'gitlens.enableRebaseEditor',
ExternalDiff = 'gitlens.externalDiff',
ExternalDiffAll = 'gitlens.externalDiffAll',
FetchRepositories = 'gitlens.fetchRepositories',

+ 25
- 0
src/commands/rebaseEditor.ts Voir le fichier

@ -0,0 +1,25 @@
'use strict';
import { command, Command, Commands } from './common';
import { Container } from '../container';
@command()
export class DisableRebaseEditorCommand extends Command {
constructor() {
super(Commands.DisableRebaseEditor);
}
execute() {
return Container.rebaseEditor.setEnabled(false);
}
}
@command()
export class EnableRebaseEditorCommand extends Command {
constructor() {
super(Commands.EnableRebaseEditor);
}
execute() {
return Container.rebaseEditor.setEnabled(true);
}
}

+ 6
- 4
src/configuration.ts Voir le fichier

@ -137,10 +137,12 @@ export class Configuration {
.get<T>(section === undefined ? extensionId : section, defaultValue)!;
}
getAny<T>(section: string, scope?: ConfigurationScope | null): T | undefined;
getAny<T>(section: string, scope: ConfigurationScope | null | undefined, defaultValue: T): T;
getAny<T>(section: string, scope?: ConfigurationScope | null, defaultValue?: T) {
return defaultValue === undefined
? workspace.getConfiguration(undefined, scope).get<T>(section)!
: workspace.getConfiguration(undefined, scope).get<T>(section, defaultValue)!;
? workspace.getConfiguration(undefined, scope).get<T>(section)
: workspace.getConfiguration(undefined, scope).get<T>(section, defaultValue);
}
changed<S1 extends keyof Config>(e: ConfigurationChangeEvent, s1: S1, scope?: ConfigurationScope | null): boolean;
@ -242,8 +244,8 @@ export class Configuration {
.inspect(section === undefined ? extensionId : section);
}
inspectAny(section: string, scope?: ConfigurationScope | null) {
return workspace.getConfiguration(undefined, scope).inspect(section);
inspectAny<T>(section: string, scope?: ConfigurationScope | null) {
return workspace.getConfiguration(undefined, scope).inspect<T>(section);
}
migrate<S1 extends keyof Config>(

+ 10
- 1
src/container.ts Voir le fichier

@ -91,7 +91,7 @@ export class Container {
});
}
context.subscriptions.push(new RebaseEditorProvider());
context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider()));
context.subscriptions.push(new GitTerminalLinkProvider());
context.subscriptions.push(new GitFileSystemProvider());
@ -237,6 +237,15 @@ export class Container {
return this._lineTracker;
}
private static _rebaseEditor: RebaseEditorProvider | undefined;
static get rebaseEditor() {
if (this._rebaseEditor === undefined) {
this._context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider()));
}
return this._rebaseEditor;
}
private static _remotesView: RemotesView | undefined;
static get remotesView() {
if (this._remotesView === undefined) {

BIN
src/webviews/apps/images/settings/rebase-editor.png Voir le fichier

Avant Après
Largeur: 645  |  Hauteur: 441  |  Taille: 45 KiB

+ 5
- 2
src/webviews/apps/rebase/rebase.html Voir le fichier

@ -27,10 +27,13 @@
<span class="shortcut"><kbd>alt ↓</kbd><span>Move Down</span></span>
</div>
<div class="actions">
<button name="start" class="button button--flat-primary" data-action="start">
<button name="disable" class="button button--flat-subtle" data-action="disable" tabindex="-1">
Disable Rebase Editor<span class="shortcut">Will Abort Rebase</span>
</button>
<button name="start" class="button button--flat-primary button--right" data-action="start">
Start Rebase <span class="shortcut">Ctrl+Enter</span>
</button>
<button name="abort" class="button button--flat" data-action="abort">
<button name="abort" class="button button--flat-secondary" data-action="abort">
Abort <span class="shortcut">Ctrl+A</span>
</button>
</div>

+ 12
- 0
src/webviews/apps/rebase/rebase.ts Voir le fichier

@ -7,6 +7,7 @@ import {
RebaseDidAbortCommandType,
RebaseDidChangeEntryCommandType,
RebaseDidChangeNotificationType,
RebaseDidDisableCommandType,
RebaseDidMoveEntryCommandType,
RebaseDidStartCommandType,
RebaseEntry,
@ -124,6 +125,7 @@ class RebaseEditor extends App {
}),
DOM.on('[data-action="start"]', 'click', () => this.onStartClicked()),
DOM.on('[data-action="abort"]', 'click', () => this.onAbortClicked()),
DOM.on('[data-action="disable"]', 'click', () => this.onDisableClicked()),
DOM.on('li[data-ref]', 'keydown', function (this: Element, e: KeyboardEvent) {
if ((e.target as HTMLElement).matches('select[data-ref]')) {
if (e.key === 'Escape') {
@ -134,6 +136,10 @@ class RebaseEditor extends App {
}
if (e.key === 'Enter' || e.key === ' ') {
if (e.key === 'Enter' && (e.target as HTMLElement).matches('a.entry-ref')) {
return;
}
const $select = (this as HTMLLIElement).querySelectorAll<HTMLSelectElement>('select[data-ref]')[0];
if ($select != null) {
$select.focus();
@ -224,6 +230,10 @@ class RebaseEditor extends App {
this.sendCommand(RebaseDidAbortCommandType, {});
}
private onDisableClicked() {
this.sendCommand(RebaseDidDisableCommandType, {});
}
private onSelectChanged($el: HTMLSelectElement) {
const ref = $el.dataset.ref;
if (ref) {
@ -367,6 +377,8 @@ class RebaseEditor extends App {
$select.appendChild(option);
}
$selectContainer.appendChild($select);
} else {
$entry.tabIndex = -1;
}
const $message = document.createElement('span');

+ 61
- 0
src/webviews/apps/scss/buttons.scss Voir le fichier

@ -116,3 +116,64 @@
transition-duration: 0s !important;
}
}
.button--flat-secondary {
background-color: var(--color-button-secondary-background);
border: 1px solid var(--color-button-secondary-background);
color: var(--color-button-foreground);
font-weight: 600;
transition: background-color 250ms, border-color 250ms, color 250ms;
&:not([disabled]):hover,
&:not([disabled]):focus {
.vscode-dark & {
background-color: white;
border-color: white;
color: black;
}
.vscode-light & {
background-color: var(--color-button-secondary-background--darken-30);
border-color: var(--color-button-secondary-background--darken-30);
color: white;
}
}
.preload & {
transition-duration: 0s !important;
}
}
.button--flat-subtle {
.vscode-light & {
border: 1px solid rgba(0, 0, 0, 0.2);
color: rgba(0, 0, 0, 0.6);
}
.vscode-dark & {
border: 1px solid rgba(255, 255, 255, 0.2);
color: rgba(255, 255, 255, 0.6);
}
transition: background-color 250ms, border-color 250ms, color 250ms;
&:not([disabled]):hover,
&:not([disabled]):focus {
.vscode-light & {
background-color: var(--color-button-secondary-background--darken-30);
border-color: var(--color-button-secondary-background--darken-30);
color: white;
}
.vscode-dark & {
background-color: white;
border-color: white;
color: black;
}
}
.preload & {
transition-duration: 0s !important;
}
}
.button--right {
margin-left: auto;
}

+ 15
- 3
src/webviews/apps/scss/rebase.scss Voir le fichier

@ -11,7 +11,7 @@ body {
font-size: 1.3em;
grid-template-areas: 'header' 'entries' 'shortcuts' 'actions';
grid-template-columns: repeat(1, 1fr min-content);
margin: 1em auto;
margin: 0 auto;
grid-gap: 0.5em 0;
max-width: 1200px;
min-width: 450px;
@ -20,11 +20,21 @@ body {
header {
display: flex;
align-items: baseline;
margin: 0 0 1em 0;
margin: 0;
h2 {
flex: auto 1 1;
margin-top: 0.5em;
font-size: 2.3rem;
}
h4 {
flex: 100% 1 1;
}
}
h4 {
font-size: 1em;
font-size: 1.5rem;
opacity: 0.8;
}
@ -60,6 +70,7 @@ h4 {
.actions {
grid-area: actions;
margin: 10px;
display: flex;
}
$entry-padding: 5px;
@ -95,6 +106,7 @@ $entry-padding: 5px;
&.entry--base {
margin-left: 10px;
margin-top: 5px;
.vscode-dark & {
background: rgba(255, 255, 255, 0.1);

+ 39
- 0
src/webviews/apps/settings/partials/rebase-editor.html Voir le fichier

@ -0,0 +1,39 @@
<section id="rebase-editor" class="section--settings section--collapsible">
<div class="section__header">
<div class="setting__input setting__input--big">
<input
id="rebaseEditor.enabled"
name="rebaseEditor.enabled"
type="checkbox"
data-setting
data-setting-type="custom"
/>
<label for="rebaseEditor.enabled">Interactive Rebase Editor</label>
<a
class="link__learn-more"
title="Learn more"
href="https://github.com/eamodio/vscode-gitlens/#interactive-rebase-editor-"
>
<i class="icon icon__info"></i>
</a>
</div>
<p class="section__header-hint">
Adds a user-friendly interactive rebase editor to easily configure an interactive rebase session
</p>
</div>
<div class="section__collapsible">
<div class="section__group">
<div class="section__content"></div>
<div class="section__preview">
<img
class="image__preview hidden"
src="#{root}/images/settings/rebase-editor.webp"
data-visibility="rebaseEditor.enabled"
/>
</div>
</div>
</div>
</section>

+ 12
- 0
src/webviews/apps/settings/settings.html Voir le fichier

@ -254,6 +254,8 @@
<!-- prettier-ignore -->
<%= require('html-loader!./partials/heatmap.html') %>
<!-- prettier-ignore -->
<%= require('html-loader!./partials/rebase-editor.html') %>
<!-- prettier-ignore -->
<%= require('html-loader!./partials/dates.html') %>
<!-- prettier-ignore -->
<%= require('html-loader!./partials/menus.html') %>
@ -444,6 +446,16 @@
<a
class="sidebar__jump-link"
data-action="jump"
href="#rebase-editor"
title="Jump to Interactive Rebase Editor settings"
>Interactive Rebase Editor</a
>
</li>
<li class="mt-1">
<a
class="sidebar__jump-link"
data-action="jump"
href="#dates"
title="Jump to Dates & Times settings"
>Dates & Times</a

+ 16
- 1
src/webviews/apps/shared/appWithConfigBase.ts Voir le fichier

@ -87,6 +87,7 @@ export abstract class AppWithConfig extends A
case DidChangeConfigurationNotificationType.method:
onIpcNotification(DidChangeConfigurationNotificationType, msg, params => {
this.state.config = params.config;
this.state.customSettings = params.customSettings;
this.updateState();
});
@ -184,6 +185,11 @@ export abstract class AppWithConfig extends A
break;
}
case 'custom': {
this._changes[element.name] = element.checked;
break;
}
default: {
if (element.checked) {
this._changes[element.name] = fromCheckboxValue(element.value);
@ -311,7 +317,14 @@ export abstract class AppWithConfig extends A
return state;
}
private getCustomSettingValue(path: string): boolean | undefined {
return this.state.customSettings?.[path];
}
private getSettingValue<T>(path: string): T | undefined {
const customSetting = this.getCustomSettingValue(path);
if (customSetting != null) return customSetting as any;
return get<T>(this.state.config, path);
}
@ -320,7 +333,9 @@ export abstract class AppWithConfig extends A
try {
for (const el of document.querySelectorAll<HTMLInputElement>('input[type=checkbox][data-setting]')) {
if (el.dataset.settingType === 'array') {
if (el.dataset.settingType === 'custom') {
el.checked = this.getCustomSettingValue(el.name) ?? false;
} else if (el.dataset.settingType === 'array') {
el.checked = (this.getSettingValue<string[]>(el.name) ?? []).includes(el.value);
} else if (el.dataset.valueOff != null) {
const value = this.getSettingValue<string>(el.name);

+ 4
- 0
src/webviews/apps/shared/theme.ts Voir le fichier

@ -43,6 +43,10 @@ export function initializeAndWatchThemeColors() {
bodyStyle.setProperty('--color-button-background', color);
bodyStyle.setProperty('--color-button-background--darken-30', darken(color, 30));
color = computedStyle.getPropertyValue('--vscode-button-secondaryBackground').trim();
bodyStyle.setProperty('--color-button-secondary-background', color);
bodyStyle.setProperty('--color-button-secondary-background--darken-30', darken(color, 30));
color = computedStyle.getPropertyValue('--vscode-button-background').trim();
bodyStyle.setProperty('--color-highlight', color);
bodyStyle.setProperty('--color-highlight--75', opacity(color, 75));

+ 10
- 6
src/webviews/protocol.ts Voir le fichier

@ -37,6 +37,7 @@ export function onIpcNotification(
export interface DidChangeConfigurationNotificationParams {
config: Config;
customSettings: Record<string, boolean>;
}
export const DidChangeConfigurationNotificationType = new IpcNotificationType<DidChangeConfigurationNotificationParams>(
'configuration/didChange',
@ -73,19 +74,20 @@ export interface DidPreviewConfigurationNotificationParams {
id: string;
preview: string;
}
export const DidPreviewConfigurationNotificationType = new IpcNotificationType<
DidPreviewConfigurationNotificationParams
>('configuration/didPreview');
export const DidPreviewConfigurationNotificationType = new IpcNotificationType<DidPreviewConfigurationNotificationParams>(
'configuration/didPreview',
);
export interface SettingsDidRequestJumpToNotificationParams {
anchor: string;
}
export const SettingsDidRequestJumpToNotificationType = new IpcNotificationType<
SettingsDidRequestJumpToNotificationParams
>('settings/jumpTo');
export const SettingsDidRequestJumpToNotificationType = new IpcNotificationType<SettingsDidRequestJumpToNotificationParams>(
'settings/jumpTo',
);
export interface AppStateWithConfig {
config: Config;
customSettings?: Record<string, boolean>;
}
export interface SettingsState extends AppStateWithConfig {
@ -132,6 +134,8 @@ export const RebaseDidStartCommandType = new IpcCommandType('rebase/start');
export const RebaseDidAbortCommandType = new IpcCommandType('rebase/abort');
export const RebaseDidDisableCommandType = new IpcCommandType('rebase/disable');
export interface RebaseDidChangeEntryCommandParams {
ref: string;
action: RebaseEntryAction;

+ 98
- 16
src/webviews/rebaseEditor.ts Voir le fichier

@ -2,6 +2,7 @@
import { TextDecoder } from 'util';
import {
CancellationToken,
ConfigurationTarget,
CustomTextEditorProvider,
Disposable,
Position,
@ -15,6 +16,7 @@ import {
WorkspaceEdit,
} from 'vscode';
import { ShowQuickCommitCommand } from '../commands';
import { configuration } from '../configuration';
import { Container } from '../container';
import { Logger } from '../logger';
import { debug } from '../system';
@ -26,6 +28,7 @@ import {
RebaseDidAbortCommandType,
RebaseDidChangeEntryCommandType,
RebaseDidChangeNotificationType,
RebaseDidDisableCommandType,
RebaseDidMoveEntryCommandType,
RebaseDidStartCommandType,
RebaseEntry,
@ -79,6 +82,64 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl
this._disposable.dispose();
}
get enabled(): boolean {
const associations = configuration.inspectAny<{ viewType: string; filenamePattern: string }[]>(
'workbench.editorAssociations',
)?.globalValue;
if (associations == null || associations.length === 0) return true;
const association = associations.find(a => a.filenamePattern === 'git-rebase-todo');
return association != null ? association.viewType === 'gitlens.rebase' : true;
}
private _disableAfterNextUse: boolean = false;
async enableForNextUse() {
if (!this.enabled) {
await this.setEnabled(true);
this._disableAfterNextUse = true;
}
}
async setEnabled(enabled: boolean): Promise<void> {
this._disableAfterNextUse = false;
const inspection = configuration.inspectAny<{ viewType: string; filenamePattern: string }[]>(
'workbench.editorAssociations',
);
let associations = inspection?.globalValue;
if (associations == null || associations.length === 0) {
if (enabled) return;
associations = [
{
viewType: 'default',
filenamePattern: 'git-rebase-todo',
},
];
} else {
const index = associations.findIndex(a => a.filenamePattern === 'git-rebase-todo');
if (index !== -1) {
if (enabled) {
if (associations.length === 1) {
associations = undefined;
} else {
associations.splice(index, 1);
}
} else {
associations[index].viewType = 'default';
}
} else if (!enabled) {
associations.push({
viewType: 'default',
filenamePattern: 'git-rebase-todo',
});
}
}
await configuration.updateAny('workbench.editorAssociations', associations, ConfigurationTarget.Global);
}
@debug<RebaseEditorProvider['resolveCustomTextEditor']>({ args: false })
async resolveCustomTextEditor(document: TextDocument, panel: WebviewPanel, _token: CancellationToken) {
const disposable = Disposable.from(
@ -95,6 +156,11 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl
panel.webview.options = { enableCommandUris: true, enableScripts: true };
panel.webview.html = await this.getHtml(panel.webview, document);
if (this._disableAfterNextUse) {
this._disableAfterNextUse = false;
void this.setEnabled(false);
}
}
private parseEntries(contents: string): RebaseEntry[];
@ -228,28 +294,24 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl
// break;
case RebaseDidStartCommandType.method:
onIpcCommand(RebaseDidStartCommandType, e, async _params => {
// Avoid triggering events by disposing them first
disposable.dispose();
case RebaseDidDisableCommandType.method:
onIpcCommand(RebaseDidDisableCommandType, e, async () => {
await this.abort(document, panel, disposable);
await this.setEnabled(false);
});
await document.save();
panel.dispose();
break;
case RebaseDidStartCommandType.method:
onIpcCommand(RebaseDidStartCommandType, e, async () => {
await this.rebase(document, panel, disposable);
});
break;
case RebaseDidAbortCommandType.method:
onIpcCommand(RebaseDidAbortCommandType, e, async _params => {
// Avoid triggering events by disposing them first
disposable.dispose();
// Delete the contents to abort the rebase
const edit = new WorkspaceEdit();
edit.replace(document.uri, new Range(0, 0, document.lineCount, 0), '');
await workspace.applyEdit(edit);
await document.save();
panel.dispose();
onIpcCommand(RebaseDidAbortCommandType, e, async () => {
await this.abort(document, panel, disposable);
});
break;
@ -395,6 +457,26 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl
}
}
private async abort(document: TextDocument, panel: WebviewPanel, disposable: Disposable) {
// Avoid triggering events by disposing them first
disposable.dispose();
// Delete the contents to abort the rebase
const edit = new WorkspaceEdit();
edit.replace(document.uri, new Range(0, 0, document.lineCount, 0), '');
await workspace.applyEdit(edit);
await document.save();
panel.dispose();
}
private async rebase(document: TextDocument, panel: WebviewPanel, disposable: Disposable) {
// Avoid triggering events by disposing them first
disposable.dispose();
await document.save();
panel.dispose();
}
private async getHtml(webview: Webview, document: TextDocument): Promise<string> {
const uri = Uri.joinPath(Container.context.extensionUri, 'dist', 'webviews', 'rebase.html');
const content = new TextDecoder('utf8').decode(await workspace.fs.readFile(uri));

+ 1
- 0
src/webviews/settingsWebview.ts Voir le fichier

@ -95,6 +95,7 @@ export class SettingsWebview extends WebviewBase {
const bootstrap: SettingsState = {
// Make sure to get the raw config, not from the container which has the modes mixed in
config: configuration.get(),
customSettings: this.getCustomSettings(),
scope: 'user',
scopes: scopes,
};

+ 69
- 2
src/webviews/webviewBase.ts Voir le fichier

@ -56,6 +56,7 @@ export abstract class WebviewBase implements Disposable {
constructor(showCommand: Commands, private readonly _column?: ViewColumn) {
this.disposable = Disposable.from(
configuration.onDidChange(this.onConfigurationChanged, this),
configuration.onDidChangeAny(this.onAnyConfigurationChanged, this),
commands.registerCommand(showCommand, this.onShowCommand, this),
);
}
@ -77,10 +78,57 @@ export abstract class WebviewBase implements Disposable {
this._disposablePanel?.dispose();
}
private _customSettings:
| Map<
string,
{
name: string;
enabled: () => boolean;
update: (enabled: boolean) => Promise<void>;
}
>
| undefined;
private get customSettings() {
if (this._customSettings == null) {
this._customSettings = new Map<
string,
{
name: string;
enabled: () => boolean;
update: (enabled: boolean) => Promise<void>;
}
>([
[
'rebaseEditor.enabled',
{
name: 'workbench.editorAssociations',
enabled: () => Container.rebaseEditor.enabled,
update: Container.rebaseEditor.setEnabled,
},
],
]);
}
return this._customSettings;
}
protected onShowCommand() {
void this.show(this._column);
}
private onAnyConfigurationChanged(e: ConfigurationChangeEvent) {
let notify = false;
for (const setting of this.customSettings.values()) {
if (e.affectsConfiguration(setting.name)) {
notify = true;
break;
}
}
if (!notify) return;
void this.notifyDidChangeConfiguration();
}
private onConfigurationChanged(_e: ConfigurationChangeEvent) {
void this.notifyDidChangeConfiguration();
}
@ -110,9 +158,17 @@ export abstract class WebviewBase implements Disposable {
params.scope === 'workspace' ? ConfigurationTarget.Workspace : ConfigurationTarget.Global;
for (const key in params.changes) {
let value = params.changes[key];
const customSetting = this.customSettings.get(key);
if (customSetting != null) {
await customSetting.update(value);
continue;
}
const inspect = configuration.inspect(key as any)!;
let value = params.changes[key];
if (value != null) {
if (params.scope === 'workspace') {
if (value === inspect.workspaceValue) continue;
@ -292,9 +348,20 @@ export abstract class WebviewBase implements Disposable {
return this.postMessage({ id: nextIpcId(), method: type.method, params: params });
}
protected getCustomSettings(): Record<string, boolean> {
const customSettings = Object.create(null);
for (const [key, setting] of this.customSettings) {
customSettings[key] = setting.enabled();
}
return customSettings;
}
private notifyDidChangeConfiguration() {
// Make sure to get the raw config, not from the container which has the modes mixed in
return this.notify(DidChangeConfigurationNotificationType, { config: configuration.get() });
return this.notify(DidChangeConfigurationNotificationType, {
config: configuration.get(),
customSettings: this.getCustomSettings(),
});
}
private postMessage(message: IpcMessage) {

Chargement…
Annuler
Enregistrer