Skip to content

Commit

Permalink
Add support for loading custom themes
Browse files Browse the repository at this point in the history
  • Loading branch information
banga committed Sep 15, 2024
1 parent d9d6d98 commit 4025c1a
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 20 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ git config split-diffs.theme-name monochrome-light

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

## Custom Themes

The above themes are bundled with `git-split-diffs`. You can override `theme-directory` to load custom themes from another directory. There should be a `{theme-name}.json` file in that directory for it to load. See [themes/](https://github.com/banga/git-split-diffs/tree/main/themes) for the definitions of the default themes above.

## Performance

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:
Expand All @@ -191,6 +195,10 @@ See [#narrow-terminals](#narrow-terminals)

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.

### Want to remove background colors from a theme?

See [#custom-themes](#custom-themes) for instructions on customizing themes. Removing `backgroundColor` should usually work.

## Acknowledgements

- [diff-so-fancy](https://github.com/so-fancy/diff-so-fancy) for showing what's possible
Expand Down
4 changes: 1 addition & 3 deletions src/getConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@ export type Config = Theme & {
HIGHLIGHT_LINE_CHANGES: boolean;
};

export const DEFAULT_THEME_NAME = 'dark';

export const CONFIG_DEFAULTS: Omit<Config, keyof Theme> = {
MIN_LINE_WIDTH: 80,
WRAP_LINES: true,
HIGHLIGHT_LINE_CHANGES: true,
};

export function getConfig(gitConfig: GitConfig): Config {
const theme = loadTheme(gitConfig.THEME_NAME ?? DEFAULT_THEME_NAME);
const theme = loadTheme(gitConfig.THEME_DIRECTORY, gitConfig.THEME_NAME);

return {
...CONFIG_DEFAULTS,
Expand Down
6 changes: 5 additions & 1 deletion src/getGitConfig.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DEFAULT_THEME_NAME } from './getConfig';
import {
DEFAULT_MIN_LINE_WIDTH,
DEFAULT_THEME_DIRECTORY,
DEFAULT_THEME_NAME,
GitConfig,
getGitConfig,
} from './getGitConfig';
Expand All @@ -10,6 +11,7 @@ const DEFAULT_CONFIG: GitConfig = {
HIGHLIGHT_LINE_CHANGES: true,
MIN_LINE_WIDTH: DEFAULT_MIN_LINE_WIDTH,
THEME_NAME: DEFAULT_THEME_NAME,
THEME_DIRECTORY: DEFAULT_THEME_DIRECTORY,
};

describe('getGitConfig', () => {
Expand All @@ -24,13 +26,15 @@ split-diffs.wrap-lines=false
split-diffs.highlight-line-changes=false
split-diffs.min-line-width=40
split-diffs.theme-name=arctic
split-diffs.theme-directory=/tmp
split-diffs.syntax-highlighting-theme=dark-plus
`)
).toEqual({
WRAP_LINES: false,
HIGHLIGHT_LINE_CHANGES: false,
MIN_LINE_WIDTH: 40,
THEME_NAME: 'arctic',
THEME_DIRECTORY: '/tmp',
SYNTAX_HIGHLIGHTING_THEME: 'dark-plus',
});
});
Expand Down
11 changes: 11 additions & 0 deletions src/getGitConfig.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import path from 'path';
import { fileURLToPath } from 'url';

export type GitConfig = {
MIN_LINE_WIDTH: number;
WRAP_LINES: boolean;
HIGHLIGHT_LINE_CHANGES: boolean;
THEME_DIRECTORY: string;
THEME_NAME: string;
SYNTAX_HIGHLIGHTING_THEME?: string;
};

export const DEFAULT_MIN_LINE_WIDTH = 80;
export const DEFAULT_THEME_DIRECTORY = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
'..',
'themes'
);
export const DEFAULT_THEME_NAME = 'dark';

const GIT_CONFIG_KEY_PREFIX = 'split-diffs';
Expand Down Expand Up @@ -44,6 +53,8 @@ export function getGitConfig(configString: string): GitConfig {
MIN_LINE_WIDTH: minLineWidth,
WRAP_LINES: rawConfig['wrap-lines'] !== 'false',
HIGHLIGHT_LINE_CHANGES: rawConfig['highlight-line-changes'] !== 'false',
THEME_DIRECTORY:
rawConfig['theme-directory'] ?? DEFAULT_THEME_DIRECTORY,
THEME_NAME: rawConfig['theme-name'] ?? DEFAULT_THEME_NAME,
SYNTAX_HIGHLIGHTING_THEME: rawConfig['syntax-highlighting-theme'],
};
Expand Down
20 changes: 14 additions & 6 deletions src/previewTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ import { Config } from './getConfig';
import { getContextForConfig } from './context';
import { loadTheme } from './themes';
import { transformContentsStreaming } from './transformContentsStreaming';
import { DEFAULT_THEME_DIRECTORY } from './getGitConfig';

const CONFIG = {
MIN_LINE_WIDTH: 40,
WRAP_LINES: true,
HIGHLIGHT_LINE_CHANGES: true,
};

async function previewTheme(themeName: string, content: string) {
const theme = loadTheme(themeName);
async function previewTheme(
themeDirectory: string,
themeName: string,
content: string
) {
const theme = loadTheme(themeDirectory, themeName);

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

function main() {
if (process.argv.length !== 4) {
console.error(`Usage: ${process.argv[1]} <sha> <theme name>`);
if (process.argv.length < 4) {
console.error(
`Usage: ${process.argv[1]} <sha> <theme name> [theme directory]`
);
process.exit(1);
}

const [, , sha, themeName] = process.argv;
const [, , sha, themeName, themeDirectory = DEFAULT_THEME_DIRECTORY] =
process.argv;

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

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

previewTheme(themeName, content);
previewTheme(themeDirectory, themeName, content);
}

main();
17 changes: 7 additions & 10 deletions src/themes.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import * as assert from 'assert';
import * as path from 'path';
import * as fs from 'fs';
import { fileURLToPath } from 'url';
import * as shiki from 'shiki';

const THEMES_DIR = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
'..',
'themes'
);
/**
* Colors are always specified as hex strings
*/
Expand Down Expand Up @@ -165,14 +159,17 @@ export function parseColorDefinition(definition: ColorDefinition): ThemeColor {
};
}

function loadThemeDefinition(themeName: string): ThemeDefinition {
function loadThemeDefinition(
themesDir: string,
themeName: string
): ThemeDefinition {
return JSON.parse(
fs.readFileSync(path.join(THEMES_DIR, `${themeName}.json`)).toString()
fs.readFileSync(path.join(themesDir, `${themeName}.json`)).toString()
) as ThemeDefinition;
}

export function loadTheme(themeName: string): Theme {
const themeDefinition = loadThemeDefinition(themeName);
export function loadTheme(themesDir: string, themeName: string): Theme {
const themeDefinition = loadThemeDefinition(themesDir, themeName);

const theme: Partial<Theme> = {
SYNTAX_HIGHLIGHTING_THEME: themeDefinition.SYNTAX_HIGHLIGHTING_THEME,
Expand Down

0 comments on commit 4025c1a

Please sign in to comment.