add profiles to config

This commit is contained in:
Labhansh Agrawal 2023-06-29 11:51:51 +05:30
parent 632bc73053
commit f0316e90c9
12 changed files with 533 additions and 378 deletions

View file

@ -78,8 +78,30 @@ export const getConfigDir = () => {
return cfgDir; return cfgDir;
}; };
export const getDefaultProfile = () => {
return cfg.config.defaultProfile || cfg.config.profiles[0]?.name || 'default';
};
// get config for the default profile, keeping it for backward compatibility
export const getConfig = () => { export const getConfig = () => {
return cfg.config; return getProfileConfig(getDefaultProfile());
};
export const getProfiles = () => {
return cfg.config.profiles;
};
export const getProfileConfig = (profileName: string): configOptions => {
const {profiles, defaultProfile, ...baseConfig} = cfg.config;
const profileConfig = profiles.find((p) => p.name === profileName)?.config || {};
for (const key in profileConfig) {
if (typeof baseConfig[key] === 'object' && !Array.isArray(baseConfig[key])) {
baseConfig[key] = {...baseConfig[key], ...profileConfig[key]};
} else {
baseConfig[key] = profileConfig[key];
}
}
return {...baseConfig, defaultProfile, profiles};
}; };
export const openConfig = () => { export const openConfig = () => {

View file

@ -62,7 +62,14 @@
"autoUpdatePlugins": true, "autoUpdatePlugins": true,
"preserveCWD": true, "preserveCWD": true,
"screenReaderMode": false, "screenReaderMode": false,
"imageSupport": true "imageSupport": true,
"defaultProfile": "default",
"profiles": [
{
"name": "default",
"config": {}
}
]
}, },
"plugins": [], "plugins": [],
"localPlugins": [], "localPlugins": [],

View file

@ -32,7 +32,19 @@ const _init = (userCfg: rawConfig, defaultCfg: rawConfig): parsedConfig => {
return { return {
config: (() => { config: (() => {
if (userCfg?.config) { if (userCfg?.config) {
return _.merge({}, defaultCfg.config, userCfg.config); const conf = userCfg.config;
conf.defaultProfile = conf.defaultProfile || 'default';
conf.profiles = conf.profiles || [];
conf.profiles = conf.profiles.length > 0 ? conf.profiles : [{name: 'default', config: {}}];
conf.profiles = conf.profiles.map((p, i) => ({
...p,
name: p.name || `profile-${i + 1}`,
config: p.config || {}
}));
if (!conf.profiles.map((p) => p.name).includes(conf.defaultProfile)) {
conf.defaultProfile = conf.profiles[0].name;
}
return _.merge({}, defaultCfg.config, conf);
} else { } else {
notify('Error reading configuration: `config` key is missing'); notify('Error reading configuration: `config` key is missing');
return defaultCfg.config || ({} as configOptions); return defaultCfg.config || ({} as configOptions);

View file

@ -24,10 +24,37 @@
} }
], ],
"description": "A string or number representing text font weight." "description": "A string or number representing text font weight."
},
"Partial<profileConfigOptions>": {
"properties": {
"env": {
"additionalProperties": {
"type": "string"
},
"description": "for environment variables",
"type": "object"
},
"shell": {
"description": "the shell to run when spawning a new session (e.g. /usr/local/bin/fish)\nif left empty, your system's login shell will be used by default\n\nWindows\n- Make sure to use a full path if the binary name doesn't work\n- Remove `--login` in shellArgs\n\nWindows Subsystem for Linux (WSL) - previously Bash on Windows\n- Example: `C:\\\\Windows\\\\System32\\\\wsl.exe`\n\nGit-bash on Windows\n- Example: `C:\\\\Program Files\\\\Git\\\\bin\\\\bash.exe`\n\nPowerShell on Windows\n- Example: `C:\\\\WINDOWS\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe`\n\nCygwin\n- Example: `C:\\\\cygwin64\\\\bin\\\\bash.exe`\n\nGit Bash\n- Example: `C:\\\\Program Files\\\\Git\\\\git-cmd.exe`\nThen Add `--command=usr/bin/bash.exe` to shellArgs",
"type": "string"
},
"shellArgs": {
"description": "for setting shell arguments (e.g. for using interactive shellArgs: `['-i']`)\nby default `['--login']` will be used",
"items": {
"type": "string"
},
"type": "array"
},
"workingDirectory": {
"description": "set custom startup directory (must be an absolute path)",
"type": "string"
} }
}, },
"properties": { "type": "object"
"config": { },
"configOptions": {
"allOf": [
{
"properties": { "properties": {
"autoUpdatePlugins": { "autoUpdatePlugins": {
"description": "if `true` (default), Hyper will update plugins every 5 hours\nyou can also set it to a custom time e.g. `1d` or `2h`", "description": "if `true` (default), Hyper will update plugins every 5 hours\nyou can also set it to a custom time e.g. `1d` or `2h`",
@ -175,13 +202,6 @@
"description": "if `false` Hyper will use ligatures provided by some fonts", "description": "if `false` Hyper will use ligatures provided by some fonts",
"type": "boolean" "type": "boolean"
}, },
"env": {
"additionalProperties": {
"type": "string"
},
"description": "for environment variables",
"type": "object"
},
"fontFamily": { "fontFamily": {
"description": "font family with optional fallbacks", "description": "font family with optional fallbacks",
"type": "string" "type": "string"
@ -256,17 +276,6 @@
"description": "terminal selection color", "description": "terminal selection color",
"type": "string" "type": "string"
}, },
"shell": {
"description": "the shell to run when spawning a new session (e.g. /usr/local/bin/fish)\nif left empty, your system's login shell will be used by default\n\nWindows\n- Make sure to use a full path if the binary name doesn't work\n- Remove `--login` in shellArgs\n\nWindows Subsystem for Linux (WSL) - previously Bash on Windows\n- Example: `C:\\\\Windows\\\\System32\\\\wsl.exe`\n\nGit-bash on Windows\n- Example: `C:\\\\Program Files\\\\Git\\\\bin\\\\bash.exe`\n\nPowerShell on Windows\n- Example: `C:\\\\WINDOWS\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe`\n\nCygwin\n- Example: `C:\\\\cygwin64\\\\bin\\\\bash.exe`\n\nGit Bash\n- Example: `C:\\\\Program Files\\\\Git\\\\git-cmd.exe`\nThen Add `--command=usr/bin/bash.exe` to shellArgs",
"type": "string"
},
"shellArgs": {
"description": "for setting shell arguments (e.g. for using interactive shellArgs: `['-i']`)\nby default `['--login']` will be used",
"items": {
"type": "string"
},
"type": "array"
},
"showHamburgerMenu": { "showHamburgerMenu": {
"description": "if you're using a Linux setup which show native menus, set to false\n\ndefault: `true` on Linux, `true` on Windows, ignored on macOS", "description": "if you're using a Linux setup which show native menus, set to false\n\ndefault: `true` on Linux, `true` on Windows, ignored on macOS",
"enum": [ "enum": [
@ -330,10 +339,6 @@
"maxItems": 2, "maxItems": 2,
"minItems": 2, "minItems": 2,
"type": "array" "type": "array"
},
"workingDirectory": {
"description": "set custom startup directory (must be an absolute path)",
"type": "string"
} }
}, },
"required": [ "required": [
@ -353,7 +358,6 @@
"defaultSSHApp", "defaultSSHApp",
"disableAutoUpdates", "disableAutoUpdates",
"disableLigatures", "disableLigatures",
"env",
"fontFamily", "fontFamily",
"fontSize", "fontSize",
"fontWeight", "fontWeight",
@ -369,18 +373,88 @@
"screenReaderMode", "screenReaderMode",
"scrollback", "scrollback",
"selectionColor", "selectionColor",
"shell",
"shellArgs",
"showHamburgerMenu", "showHamburgerMenu",
"showWindowControls", "showWindowControls",
"termCSS", "termCSS",
"updateChannel", "updateChannel",
"webGLRenderer", "webGLRenderer",
"webLinksActivationKey", "webLinksActivationKey"
],
"type": "object"
},
{
"properties": {
"env": {
"additionalProperties": {
"type": "string"
},
"description": "for environment variables",
"type": "object"
},
"shell": {
"description": "the shell to run when spawning a new session (e.g. /usr/local/bin/fish)\nif left empty, your system's login shell will be used by default\n\nWindows\n- Make sure to use a full path if the binary name doesn't work\n- Remove `--login` in shellArgs\n\nWindows Subsystem for Linux (WSL) - previously Bash on Windows\n- Example: `C:\\\\Windows\\\\System32\\\\wsl.exe`\n\nGit-bash on Windows\n- Example: `C:\\\\Program Files\\\\Git\\\\bin\\\\bash.exe`\n\nPowerShell on Windows\n- Example: `C:\\\\WINDOWS\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe`\n\nCygwin\n- Example: `C:\\\\cygwin64\\\\bin\\\\bash.exe`\n\nGit Bash\n- Example: `C:\\\\Program Files\\\\Git\\\\git-cmd.exe`\nThen Add `--command=usr/bin/bash.exe` to shellArgs",
"type": "string"
},
"shellArgs": {
"description": "for setting shell arguments (e.g. for using interactive shellArgs: `['-i']`)\nby default `['--login']` will be used",
"items": {
"type": "string"
},
"type": "array"
},
"workingDirectory": {
"description": "set custom startup directory (must be an absolute path)",
"type": "string"
}
},
"required": [
"env",
"shell",
"shellArgs",
"workingDirectory" "workingDirectory"
], ],
"type": "object" "type": "object"
}, },
{
"properties": {
"defaultProfile": {
"description": "The default profile name to use when launching a new session",
"type": "string"
},
"profiles": {
"description": "A list of profiles to use",
"items": {
"properties": {
"config": {
"$ref": "#/definitions/Partial<profileConfigOptions>",
"description": "Specify all the options you want to override for each profile.\nOptions set here override the defaults set in the root."
},
"name": {
"type": "string"
}
},
"required": [
"config",
"name"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"defaultProfile",
"profiles"
],
"type": "object"
}
]
}
},
"properties": {
"config": {
"$ref": "#/definitions/configOptions"
},
"keymaps": { "keymaps": {
"additionalProperties": { "additionalProperties": {
"anyOf": [ "anyOf": [

View file

@ -92,7 +92,7 @@ app.on('ready', () =>
fn?: (win: BrowserWindow) => void, fn?: (win: BrowserWindow) => void,
options: {size?: [number, number]; position?: [number, number]} = {} options: {size?: [number, number]; position?: [number, number]} = {}
) { ) {
const cfg = plugins.getDecoratedConfig(); const cfg = plugins.getDecoratedConfig(config.getDefaultProfile());
const winSet = config.getWin(); const winSet = config.getWin();
let [startX, startY] = winSet.position; let [startX, startY] = winSet.position;

View file

@ -425,8 +425,12 @@ export const getDecoratedEnv = (baseEnv: Record<string, string>) => {
return decorateObject(baseEnv, 'decorateEnv'); return decorateObject(baseEnv, 'decorateEnv');
}; };
export const getDecoratedConfig = () => { export const getDefaultProfile = () => {
const baseConfig = config.getConfig(); return config.getDefaultProfile();
};
export const getDecoratedConfig = (profile: string) => {
const baseConfig = config.getProfileConfig(profile);
const decoratedConfig = decorateObject(baseConfig, 'decorateConfig'); const decoratedConfig = decorateObject(baseConfig, 'decorateConfig');
const fixedConfig = config.fixConfigDefaults(decoratedConfig); const fixedConfig = config.fixConfigDefaults(decoratedConfig);
const translatedConfig = config.htermConfigTranslate(fixedConfig); const translatedConfig = config.htermConfigTranslate(fixedConfig);

View file

@ -20,6 +20,7 @@ import type {configOptions} from '../../lib/config';
import {getWorkingDirectoryFromPID} from 'native-process-working-directory'; import {getWorkingDirectoryFromPID} from 'native-process-working-directory';
import {existsSync} from 'fs'; import {existsSync} from 'fs';
import type {sessionExtraOptions} from '../../common'; import type {sessionExtraOptions} from '../../common';
import {getDefaultProfile} from '../config';
export function newWindow( export function newWindow(
options_: BrowserWindowConstructorOptions, options_: BrowserWindowConstructorOptions,
@ -62,7 +63,7 @@ export function newWindow(
const sessions = new Map<string, Session>(); const sessions = new Map<string, Session>();
const updateBackgroundColor = () => { const updateBackgroundColor = () => {
const cfg_ = app.plugins.getDecoratedConfig(); const cfg_ = app.plugins.getDecoratedConfig(getDefaultProfile());
window.setBackgroundColor(toElectronBackgroundColor(cfg_.backgroundColor || '#000')); window.setBackgroundColor(toElectronBackgroundColor(cfg_.backgroundColor || '#000'));
}; };
@ -83,7 +84,7 @@ export function newWindow(
// config changes // config changes
const cfgUnsubscribe = app.config.subscribe(() => { const cfgUnsubscribe = app.config.subscribe(() => {
const cfg_ = app.plugins.getDecoratedConfig(); const cfg_ = app.plugins.getDecoratedConfig(getDefaultProfile());
// notify renderer // notify renderer
window.webContents.send('config change'); window.webContents.send('config change');

View file

@ -8,6 +8,7 @@ import retry from 'async-retry';
import {version} from './package.json'; import {version} from './package.json';
import {getDecoratedConfig} from './plugins'; import {getDecoratedConfig} from './plugins';
import autoUpdaterLinux from './auto-updater-linux'; import autoUpdaterLinux from './auto-updater-linux';
import {getDefaultProfile} from './config';
const {platform} = process; const {platform} = process;
const isLinux = platform === 'linux'; const isLinux = platform === 'linux';
@ -16,7 +17,7 @@ const autoUpdater: AutoUpdater = isLinux ? autoUpdaterLinux : electron.autoUpdat
const getDecoratedConfigWithRetry = async () => { const getDecoratedConfigWithRetry = async () => {
return await retry(() => { return await retry(() => {
const content = getDecoratedConfig(); const content = getDecoratedConfig(getDefaultProfile());
if (!content) { if (!content) {
throw new Error('No config content loaded'); throw new Error('No config content loaded');
} }

92
lib/config.d.ts vendored
View file

@ -19,7 +19,44 @@ export type ColorMap = {
yellow: string; yellow: string;
}; };
export type configOptions = { type profileConfigOptions = {
/** for environment variables */
env: {[k: string]: string};
/**
* the shell to run when spawning a new session (e.g. /usr/local/bin/fish)
* if left empty, your system's login shell will be used by default
*
* Windows
* - Make sure to use a full path if the binary name doesn't work
* - Remove `--login` in shellArgs
*
* Windows Subsystem for Linux (WSL) - previously Bash on Windows
* - Example: `C:\\Windows\\System32\\wsl.exe`
*
* Git-bash on Windows
* - Example: `C:\\Program Files\\Git\\bin\\bash.exe`
*
* PowerShell on Windows
* - Example: `C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`
*
* Cygwin
* - Example: `C:\\cygwin64\\bin\\bash.exe`
*
* Git Bash
* - Example: `C:\\Program Files\\Git\\git-cmd.exe`
* Then Add `--command=usr/bin/bash.exe` to shellArgs
*/
shell: string;
/**
* for setting shell arguments (e.g. for using interactive shellArgs: `['-i']`)
* by default `['--login']` will be used
*/
shellArgs: string[];
/** set custom startup directory (must be an absolute path) */
workingDirectory: string;
};
type rootConfigOptions = {
/** /**
* if `true` (default), Hyper will update plugins every 5 hours * if `true` (default), Hyper will update plugins every 5 hours
* you can also set it to a custom time e.g. `1d` or `2h` * you can also set it to a custom time e.g. `1d` or `2h`
@ -74,8 +111,6 @@ export type configOptions = {
disableAutoUpdates: boolean; disableAutoUpdates: boolean;
/** if `false` Hyper will use ligatures provided by some fonts */ /** if `false` Hyper will use ligatures provided by some fonts */
disableLigatures: boolean; disableLigatures: boolean;
/** for environment variables */
env: {[k: string]: string};
/** font family with optional fallbacks */ /** font family with optional fallbacks */
fontFamily: string; fontFamily: string;
/** default font size in pixels for all tabs */ /** default font size in pixels for all tabs */
@ -122,36 +157,6 @@ export type configOptions = {
scrollback: number; scrollback: number;
/** terminal selection color */ /** terminal selection color */
selectionColor: string; selectionColor: string;
/**
* the shell to run when spawning a new session (e.g. /usr/local/bin/fish)
* if left empty, your system's login shell will be used by default
*
* Windows
* - Make sure to use a full path if the binary name doesn't work
* - Remove `--login` in shellArgs
*
* Windows Subsystem for Linux (WSL) - previously Bash on Windows
* - Example: `C:\\Windows\\System32\\wsl.exe`
*
* Git-bash on Windows
* - Example: `C:\\Program Files\\Git\\bin\\bash.exe`
*
* PowerShell on Windows
* - Example: `C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`
*
* Cygwin
* - Example: `C:\\cygwin64\\bin\\bash.exe`
*
* Git Bash
* - Example: `C:\\Program Files\\Git\\git-cmd.exe`
* Then Add `--command=usr/bin/bash.exe` to shellArgs
*/
shell: string;
/**
* for setting shell arguments (e.g. for using interactive shellArgs: `['-i']`)
* by default `['--login']` will be used
*/
shellArgs: string[];
/** /**
* if you're using a Linux setup which show native menus, set to false * if you're using a Linux setup which show native menus, set to false
* *
@ -184,10 +189,27 @@ export type configOptions = {
webLinksActivationKey: 'ctrl' | 'alt' | 'meta' | 'shift' | ''; webLinksActivationKey: 'ctrl' | 'alt' | 'meta' | 'shift' | '';
/** Initial window size in pixels */ /** Initial window size in pixels */
windowSize?: [number, number]; windowSize?: [number, number];
/** set custom startup directory (must be an absolute path) */
workingDirectory: string;
}; };
export type configOptions = rootConfigOptions &
profileConfigOptions & {
/**
* The default profile name to use when launching a new session
*/
defaultProfile: string;
/**
* A list of profiles to use
*/
profiles: {
name: string;
/**
* Specify all the options you want to override for each profile.
* Options set here override the defaults set in the root.
*/
config: Partial<profileConfigOptions>;
}[];
};
export type rawConfig = { export type rawConfig = {
config?: configOptions; config?: configOptions;
/** /**

4
lib/hyper.d.ts vendored
View file

@ -39,7 +39,7 @@ export type ITermState = Immutable<{
export type cursorShapes = 'BEAM' | 'UNDERLINE' | 'BLOCK'; export type cursorShapes = 'BEAM' | 'UNDERLINE' | 'BLOCK';
import type {FontWeight, IWindowsPty, Terminal} from 'xterm'; import type {FontWeight, IWindowsPty, Terminal} from 'xterm';
import type {ColorMap} from './config'; import type {ColorMap, configOptions} from './config';
export type uiState = Immutable<{ export type uiState = Immutable<{
_lastUpdate: number | null; _lastUpdate: number | null;
@ -105,6 +105,8 @@ export type uiState = Immutable<{
webGLRenderer: boolean; webGLRenderer: boolean;
webLinksActivationKey: 'ctrl' | 'alt' | 'meta' | 'shift' | ''; webLinksActivationKey: 'ctrl' | 'alt' | 'meta' | 'shift' | '';
windowsPty?: IWindowsPty; windowsPty?: IWindowsPty;
defaultProfile: string;
profiles: configOptions['profiles'];
}>; }>;
export type session = { export type session = {

View file

@ -113,7 +113,9 @@ const initial: uiState = Immutable<Mutable<uiState>>({
webLinksActivationKey: '', webLinksActivationKey: '',
macOptionSelectionMode: 'vertical', macOptionSelectionMode: 'vertical',
disableLigatures: true, disableLigatures: true,
screenReaderMode: false screenReaderMode: false,
defaultProfile: '',
profiles: []
}); });
const reducer: IUiReducer = (state = initial, action) => { const reducer: IUiReducer = (state = initial, action) => {
@ -287,6 +289,14 @@ const reducer: IUiReducer = (state = initial, action) => {
ret.imageSupport = config.imageSupport; ret.imageSupport = config.imageSupport;
} }
if (config.defaultProfile !== undefined) {
ret.defaultProfile = config.defaultProfile;
}
if (config.profiles !== undefined) {
ret.profiles = config.profiles;
}
ret._lastUpdate = now; ret._lastUpdate = now;
return ret; return ret;

View file

@ -5,7 +5,7 @@ import {require as remoteRequire} from '@electron/remote';
const plugins = remoteRequire('./plugins') as typeof import('../../app/plugins'); const plugins = remoteRequire('./plugins') as typeof import('../../app/plugins');
export function getConfig() { export function getConfig() {
return plugins.getDecoratedConfig(); return plugins.getDecoratedConfig(plugins.getDefaultProfile());
} }
export function subscribe(fn: (event: Electron.IpcRendererEvent, ...args: any[]) => void) { export function subscribe(fn: (event: Electron.IpcRendererEvent, ...args: any[]) => void) {