Skip to content

Commit a21adbb

Browse files
committed
Add support for loading custom themes
1 parent d9d6d98 commit a21adbb

File tree

6 files changed

+53
-20
lines changed

6 files changed

+53
-20
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,17 @@ git config split-diffs.theme-name monochrome-light
171171

172172
![Screenshot of Monochrome Light theme](screenshots/monochrome-light.png?raw=true)
173173

174+
## Custom Themes
175+
176+
Default themes are loaded from the `git-split-diffs` bundle. To load a custom theme, set `theme-directory` in git config and create a `{theme-name}.json` file in that directory with the theme's definition. You can use one of the existing themes in [themes/](https://github.com/banga/git-split-diffs/tree/main/themes) as a starting point.
177+
178+
```
179+
git config split-diffs.theme-directory </path/to/theme>
180+
git config split-diffs.theme-name <name>
181+
```
182+
183+
This will use `/path/to/theme/name.json` as the theme.
184+
174185
## Performance
175186

176187
Tested by measuring the time it took to pipe the output `git log -p` to `/dev/null` via `git-split-diffs` with the default theme:
@@ -191,6 +202,10 @@ See [#narrow-terminals](#narrow-terminals)
191202

192203
Text coloring is implemented using Chalk which supports [various levels of color](https://github.com/chalk/chalk#supportscolor). If Chalk is producing fewer colors than your terminal supports, try overriding Chalk's detection using a variation of the `--color` flag, e.g. `--color=16m` for true color. See Chalk's documentation or [this useful gist on terminal support](https://gist.github.com/XVilka/8346728) if issues persist.
193204

205+
### Want to remove background colors from a theme?
206+
207+
See [#custom-themes](#custom-themes) for instructions on customizing themes. Removing `backgroundColor` should usually work.
208+
194209
## Acknowledgements
195210

196211
- [diff-so-fancy](https://github.com/so-fancy/diff-so-fancy) for showing what's possible

src/getConfig.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@ export type Config = Theme & {
88
HIGHLIGHT_LINE_CHANGES: boolean;
99
};
1010

11-
export const DEFAULT_THEME_NAME = 'dark';
12-
1311
export const CONFIG_DEFAULTS: Omit<Config, keyof Theme> = {
1412
MIN_LINE_WIDTH: 80,
1513
WRAP_LINES: true,
1614
HIGHLIGHT_LINE_CHANGES: true,
1715
};
1816

1917
export function getConfig(gitConfig: GitConfig): Config {
20-
const theme = loadTheme(gitConfig.THEME_NAME ?? DEFAULT_THEME_NAME);
18+
const theme = loadTheme(gitConfig.THEME_DIRECTORY, gitConfig.THEME_NAME);
2119

2220
return {
2321
...CONFIG_DEFAULTS,

src/getGitConfig.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { DEFAULT_THEME_NAME } from './getConfig';
21
import {
32
DEFAULT_MIN_LINE_WIDTH,
3+
DEFAULT_THEME_DIRECTORY,
4+
DEFAULT_THEME_NAME,
45
GitConfig,
56
getGitConfig,
67
} from './getGitConfig';
@@ -10,6 +11,7 @@ const DEFAULT_CONFIG: GitConfig = {
1011
HIGHLIGHT_LINE_CHANGES: true,
1112
MIN_LINE_WIDTH: DEFAULT_MIN_LINE_WIDTH,
1213
THEME_NAME: DEFAULT_THEME_NAME,
14+
THEME_DIRECTORY: DEFAULT_THEME_DIRECTORY,
1315
};
1416

1517
describe('getGitConfig', () => {
@@ -24,13 +26,15 @@ split-diffs.wrap-lines=false
2426
split-diffs.highlight-line-changes=false
2527
split-diffs.min-line-width=40
2628
split-diffs.theme-name=arctic
29+
split-diffs.theme-directory=/tmp
2730
split-diffs.syntax-highlighting-theme=dark-plus
2831
`)
2932
).toEqual({
3033
WRAP_LINES: false,
3134
HIGHLIGHT_LINE_CHANGES: false,
3235
MIN_LINE_WIDTH: 40,
3336
THEME_NAME: 'arctic',
37+
THEME_DIRECTORY: '/tmp',
3438
SYNTAX_HIGHLIGHTING_THEME: 'dark-plus',
3539
});
3640
});

src/getGitConfig.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1+
import path from 'path';
2+
import { fileURLToPath } from 'url';
3+
14
export type GitConfig = {
25
MIN_LINE_WIDTH: number;
36
WRAP_LINES: boolean;
47
HIGHLIGHT_LINE_CHANGES: boolean;
8+
THEME_DIRECTORY: string;
59
THEME_NAME: string;
610
SYNTAX_HIGHLIGHTING_THEME?: string;
711
};
812

913
export const DEFAULT_MIN_LINE_WIDTH = 80;
14+
export const DEFAULT_THEME_DIRECTORY = path.resolve(
15+
path.dirname(fileURLToPath(import.meta.url)),
16+
'..',
17+
'themes'
18+
);
1019
export const DEFAULT_THEME_NAME = 'dark';
1120

1221
const GIT_CONFIG_KEY_PREFIX = 'split-diffs';
@@ -44,6 +53,8 @@ export function getGitConfig(configString: string): GitConfig {
4453
MIN_LINE_WIDTH: minLineWidth,
4554
WRAP_LINES: rawConfig['wrap-lines'] !== 'false',
4655
HIGHLIGHT_LINE_CHANGES: rawConfig['highlight-line-changes'] !== 'false',
56+
THEME_DIRECTORY:
57+
rawConfig['theme-directory'] ?? DEFAULT_THEME_DIRECTORY,
4758
THEME_NAME: rawConfig['theme-name'] ?? DEFAULT_THEME_NAME,
4859
SYNTAX_HIGHLIGHTING_THEME: rawConfig['syntax-highlighting-theme'],
4960
};

src/previewTheme.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@ import { Config } from './getConfig';
66
import { getContextForConfig } from './context';
77
import { loadTheme } from './themes';
88
import { transformContentsStreaming } from './transformContentsStreaming';
9+
import { DEFAULT_THEME_DIRECTORY } from './getGitConfig';
910

1011
const CONFIG = {
1112
MIN_LINE_WIDTH: 40,
1213
WRAP_LINES: true,
1314
HIGHLIGHT_LINE_CHANGES: true,
1415
};
1516

16-
async function previewTheme(themeName: string, content: string) {
17-
const theme = loadTheme(themeName);
17+
async function previewTheme(
18+
themeDirectory: string,
19+
themeName: string,
20+
content: string
21+
) {
22+
const theme = loadTheme(themeDirectory, themeName);
1823

1924
const { rows, columns } = terminalSize();
2025
const config: Config = {
@@ -41,19 +46,22 @@ async function previewTheme(themeName: string, content: string) {
4146
}
4247

4348
function main() {
44-
if (process.argv.length !== 4) {
45-
console.error(`Usage: ${process.argv[1]} <sha> <theme name>`);
49+
if (process.argv.length < 4) {
50+
console.error(
51+
`Usage: ${process.argv[1]} <sha> <theme name> [theme directory]`
52+
);
4653
process.exit(1);
4754
}
4855

49-
const [, , sha, themeName] = process.argv;
56+
const [, , sha, themeName, themeDirectory = DEFAULT_THEME_DIRECTORY] =
57+
process.argv;
5058

5159
const content = execSync(`git show ${sha}`).toString();
5260

5361
// Clear screen
5462
process.stdout.write('\x1bc');
5563

56-
previewTheme(themeName, content);
64+
previewTheme(themeDirectory, themeName, content);
5765
}
5866

5967
main();

src/themes.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import * as assert from 'assert';
22
import * as path from 'path';
33
import * as fs from 'fs';
4-
import { fileURLToPath } from 'url';
54
import * as shiki from 'shiki';
65

7-
const THEMES_DIR = path.resolve(
8-
path.dirname(fileURLToPath(import.meta.url)),
9-
'..',
10-
'themes'
11-
);
126
/**
137
* Colors are always specified as hex strings
148
*/
@@ -165,14 +159,17 @@ export function parseColorDefinition(definition: ColorDefinition): ThemeColor {
165159
};
166160
}
167161

168-
function loadThemeDefinition(themeName: string): ThemeDefinition {
162+
function loadThemeDefinition(
163+
themesDir: string,
164+
themeName: string
165+
): ThemeDefinition {
169166
return JSON.parse(
170-
fs.readFileSync(path.join(THEMES_DIR, `${themeName}.json`)).toString()
167+
fs.readFileSync(path.join(themesDir, `${themeName}.json`)).toString()
171168
) as ThemeDefinition;
172169
}
173170

174-
export function loadTheme(themeName: string): Theme {
175-
const themeDefinition = loadThemeDefinition(themeName);
171+
export function loadTheme(themesDir: string, themeName: string): Theme {
172+
const themeDefinition = loadThemeDefinition(themesDir, themeName);
176173

177174
const theme: Partial<Theme> = {
178175
SYNTAX_HIGHLIGHTING_THEME: themeDefinition.SYNTAX_HIGHLIGHTING_THEME,

0 commit comments

Comments
 (0)