diff --git a/CHANGELOG.md b/CHANGELOG.md
index 091b86a..11b5682 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,8 @@
- Start screen of Settings UI will use the cached list of configs instead of reloading them
- This should make navigating to the start screen (especially when navigating back and forth between configs) faster
- The Refresh button is now renamed to Reload and will still reload the configs (from disk, remote workspaces, ...)
+- Add support for extending configs to the Settings UI (#268)
+ - This adds a visual editor to the Settings UI for the `extend` config option
### Development changes
diff --git a/common/src/fileSystemConfig.ts b/common/src/fileSystemConfig.ts
index ae256c3..d5db4b7 100644
--- a/common/src/fileSystemConfig.ts
+++ b/common/src/fileSystemConfig.ts
@@ -89,7 +89,7 @@ export interface FileSystemConfig extends ConnectConfig {
group?: string;
/** Whether to merge this "lower" config (e.g. from workspace settings) into higher configs (e.g. from global settings) */
merge?: boolean;
- /** Names of other configs to merge into this config. Errors if not found. Later entries have priority. Settings defined in this config itself have even higher priority */
+ /** Names of other existing configs to merge into this config. Earlier entries overridden by later entries overridden by this config itself */
extend?: string | string[];
/** Path on the remote server that should be opened by default when creating a terminal or using the `Add as Workspace folder` command/button. Defaults to `/` */
root?: string;
diff --git a/webview/src/ConfigEditor/fields.tsx b/webview/src/ConfigEditor/fields.tsx
index 3251f6d..2cabbc8 100644
--- a/webview/src/ConfigEditor/fields.tsx
+++ b/webview/src/ConfigEditor/fields.tsx
@@ -3,6 +3,7 @@ import * as React from 'react';
import { FieldCheckbox } from '../FieldTypes/checkbox';
import { FieldDropdown } from '../FieldTypes/dropdown';
import { FieldDropdownWithInput } from '../FieldTypes/dropdownwithinput';
+import { FieldConfigList } from '../FieldTypes/list';
import { FieldNumber } from '../FieldTypes/number';
import { FieldPath } from '../FieldTypes/path';
import { FieldString } from '../FieldTypes/string';
@@ -27,14 +28,6 @@ export function name(config: FileSystemConfig, onChange: FSCChanged<'name'>): Re
return
}
-export function merge(config: FileSystemConfig, onChange: FSCChanged<'merge'>): React.ReactElement {
- const callback = (newValue: string) => onChange('merge', newValue === 'Yes' || undefined);
- const description = 'Whether to merge this "lower" config (e.g. from workspace settings) into higher configs (e.g. from global settings)';
- const values = ['Yes', 'No'];
- const value = config.merge ? 'Yes' : 'No';
- return
-}
-
export function label(config: FileSystemConfig, onChange: FSCChanged<'label'>): React.ReactElement {
const callback = (newValue?: string) => onChange('label', newValue);
const description = 'Label to display in some UI places (e.g. popups)';
@@ -47,6 +40,21 @@ export function group(config: FileSystemConfig, onChange: FSCChanged<'group'>):
return
}
+export function merge(config: FileSystemConfig, onChange: FSCChanged<'merge'>): React.ReactElement {
+ const callback = (newValue: string) => onChange('merge', newValue === 'Yes' || undefined);
+ const description = 'Whether to merge this "lower" config (e.g. from workspace settings) into higher configs (e.g. from global settings)';
+ const values = ['Yes', 'No'];
+ const value = config.merge ? 'Yes' : 'No';
+ return
+}
+
+export function extend(config: FileSystemConfig, onChange: FSCChanged<'extend'>): React.ReactElement {
+ const callback = (newValue?: string | string[]) => onChange('extend', newValue);
+ const description = 'Names of other existing configs to merge into this config. Earlier entries overridden by later entries overridden by this config itself';
+ const value = typeof config.extend === 'string' ? [config.extend] : config.extend;
+ return
+}
+
export function putty(config: FileSystemConfig, onChange: FSCChanged<'putty'>): React.ReactElement {
const callback = (newValue: string) => onChange('putty', newValue === '' ? true : newValue);
const description = 'A name of a PuTTY session, or `true` to find the PuTTY session from the host address';
@@ -163,7 +171,7 @@ export function taskCommand(config: FileSystemConfig, onChange: FSCChanged<'task
export type FieldFactory = (config: FileSystemConfig, onChange: FSCChanged, onChangeMultiple: FSCChangedMultiple) => React.ReactElement | null;
export const FIELDS: FieldFactory[] = [
- name, merge, label, group, putty, host, port,
+ name, label, group, merge, extend, putty, host, port,
root, agent, username, password, privateKeyPath, passphrase,
newFileMode, agentForward, sftpCommand, sftpSudo, terminalCommand, taskCommand,
PROXY_FIELD];