@brimveyn/aimux-config 0.5.3 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/package.json +1 -1
  2. package/src/actions.ts +58 -0
  3. package/src/defaults.ts +3 -0
  4. package/src/index.ts +21 -31
  5. package/src/resolver.ts +1 -1
  6. package/src/tui/index.ts +5 -0
  7. package/src/tui/registry.ts +95 -0
  8. package/src/tui/resolve.ts +156 -0
  9. package/src/tui/shiki.ts +149 -0
  10. package/src/tui/themes/aimux.json +110 -0
  11. package/src/tui/themes/aura.json +69 -0
  12. package/src/tui/themes/ayu.json +80 -0
  13. package/src/tui/themes/carbonfox.json +248 -0
  14. package/src/tui/themes/catppuccin-frappe.json +230 -0
  15. package/src/tui/themes/catppuccin-macchiato.json +230 -0
  16. package/src/tui/themes/catppuccin.json +112 -0
  17. package/src/tui/themes/cobalt2.json +225 -0
  18. package/src/tui/themes/cursor.json +249 -0
  19. package/src/tui/themes/dracula.json +219 -0
  20. package/src/tui/themes/everforest.json +241 -0
  21. package/src/tui/themes/flexoki.json +237 -0
  22. package/src/tui/themes/github.json +233 -0
  23. package/src/tui/themes/gruvbox.json +242 -0
  24. package/src/tui/themes/kanagawa.json +77 -0
  25. package/src/tui/themes/lucent-orng.json +234 -0
  26. package/src/tui/themes/material.json +235 -0
  27. package/src/tui/themes/matrix.json +77 -0
  28. package/src/tui/themes/mercury.json +252 -0
  29. package/src/tui/themes/monokai.json +221 -0
  30. package/src/tui/themes/nightowl.json +221 -0
  31. package/src/tui/themes/nord.json +223 -0
  32. package/src/tui/themes/one-dark.json +84 -0
  33. package/src/tui/themes/opencode.json +245 -0
  34. package/src/tui/themes/orng.json +249 -0
  35. package/src/tui/themes/osaka-jade.json +93 -0
  36. package/src/tui/themes/palenight.json +222 -0
  37. package/src/tui/themes/rosepine.json +234 -0
  38. package/src/tui/themes/solarized.json +223 -0
  39. package/src/tui/themes/synthwave84.json +226 -0
  40. package/src/tui/themes/tokyonight.json +243 -0
  41. package/src/tui/themes/vercel.json +245 -0
  42. package/src/tui/themes/vesper.json +218 -0
  43. package/src/tui/themes/zenburn.json +223 -0
  44. package/src/tui/tokens.ts +111 -0
  45. package/src/tui/types.ts +30 -0
  46. package/src/types.ts +9 -35
  47. package/src/house-themes.ts +0 -55
  48. package/src/neutral-scale.ts +0 -75
  49. package/src/oklch.ts +0 -164
  50. package/src/palette-to-shiki.ts +0 -134
  51. package/src/palette-utils.ts +0 -130
  52. package/src/themes/opencode.ts +0 -1460
  53. package/src/themes.ts +0 -30
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brimveyn/aimux-config",
3
- "version": "0.5.3",
3
+ "version": "0.5.6",
4
4
  "description": "TypeScript configuration API for aimux — keymaps, themes, and backends with a fluent builder.",
5
5
  "keywords": [
6
6
  "aimux",
package/src/actions.ts CHANGED
@@ -547,6 +547,64 @@ export const gitDestructiveSelected: ActionFn = (ctx: ModeContext) => {
547
547
  return r([{ path: file.path, type: 'git-mode-set-pending-delete' }])
548
548
  }
549
549
 
550
+ export const gitToggleFoldAll: ActionFn = (ctx: ModeContext) => {
551
+ const file = selectedGitFile(ctx)
552
+ if (!file) return r([])
553
+ const key = gitFileKey(file.section, file.path)
554
+ return r([{ key, type: 'git-mode-fold-toggle-all' }])
555
+ }
556
+
557
+ export const gitStageAll: ActionFn = (ctx: ModeContext) => {
558
+ if (ctx.state.gitMode.headOffset > 0) {
559
+ return r([
560
+ {
561
+ message: 'disabled while viewing HEAD~N (press 0 or [ to return)',
562
+ type: 'git-mode-set-message',
563
+ },
564
+ ])
565
+ }
566
+ const files = ctx.state.gitPanel.files
567
+ const pending = clearPendingDelete(ctx)
568
+ if (files.length === 0) return r(pending)
569
+ const actions: AppAction[] = [...pending]
570
+ for (const f of files) {
571
+ if (f.section === 'staged') continue
572
+ actions.push({
573
+ fromSection: f.section,
574
+ path: f.path,
575
+ toSection: 'staged',
576
+ type: 'git-mode-optimistic-move',
577
+ })
578
+ }
579
+ return r(actions, [{ type: 'git-stage-all' }])
580
+ }
581
+
582
+ export const gitUnstageAll: ActionFn = (ctx: ModeContext) => {
583
+ if (ctx.state.gitMode.headOffset > 0) {
584
+ return r([
585
+ {
586
+ message: 'disabled while viewing HEAD~N (press 0 or [ to return)',
587
+ type: 'git-mode-set-message',
588
+ },
589
+ ])
590
+ }
591
+ const files = ctx.state.gitPanel.files
592
+ const pending = clearPendingDelete(ctx)
593
+ if (files.length === 0) return r(pending)
594
+ const actions: AppAction[] = [...pending]
595
+ for (const f of files) {
596
+ if (f.section !== 'staged') continue
597
+ const toSection = f.status === 'A' ? 'untracked' : 'unstaged'
598
+ actions.push({
599
+ fromSection: 'staged',
600
+ path: f.path,
601
+ toSection,
602
+ type: 'git-mode-optimistic-move',
603
+ })
604
+ }
605
+ return r(actions, [{ type: 'git-unstage-all' }])
606
+ }
607
+
550
608
  export const gitCommitOpen: ActionFn = (ctx: ModeContext) => {
551
609
  if (ctx.state.gitMode.headOffset > 0) {
552
610
  return r([
package/src/defaults.ts CHANGED
@@ -98,7 +98,10 @@ export function getDefaultKeymapConfig(): ResolvedKeymapConfig {
98
98
  .mode('git-mode', (m) =>
99
99
  m
100
100
  .map('a', actions.gitStageSelected, 'Stage')
101
+ .map('A', actions.gitStageAll, 'Stage all')
101
102
  .map('d', actions.gitDestructiveSelected, 'Unstage/delete')
103
+ .map('D', actions.gitUnstageAll, 'Unstage all')
104
+ .map('e', actions.gitToggleFoldAll, 'Expand/collapse all folds')
102
105
  .map('c', actions.gitCommitOpen, 'Commit')
103
106
  .map('p', actions.gitPush, 'Push')
104
107
  .map('v', actions.toggleGitDiffView, 'Toggle split/stacked')
package/src/index.ts CHANGED
@@ -1,26 +1,27 @@
1
- // Public API — this is what users import from '@brimveyn/aimux-config'
1
+ // Public API — what users import from '@brimveyn/aimux-config'.
2
2
 
3
3
  export { defineConfig } from './define-config'
4
4
  export * as actions from './actions'
5
- export { isKnownThemeId, migrateThemeId, THEME_IDS, THEMES } from './themes'
6
- export { HOUSE_THEME_IDS, HOUSE_THEMES } from './house-themes'
7
- export { OPENCODE_THEME_IDS, OPENCODE_THEMES } from './themes/opencode'
5
+
6
+ // TUI theme system (1:1 port of opencode TUI).
8
7
  export {
9
- accent,
10
- border,
11
- computeSurfaces,
12
- diffAddBg,
13
- diffDeleteBg,
14
- elevated,
15
- extendPalette,
16
- faint,
17
- hover,
18
- mix,
19
- muted,
20
- selected,
21
- } from './palette-utils'
22
- export type { ResolvedSurfaces } from './palette-utils'
23
- export { paletteToShikiTheme } from './palette-to-shiki'
8
+ isKnownThemeId,
9
+ migrateThemeId,
10
+ type ResolvedTuiTheme,
11
+ resolveTuiTheme,
12
+ type RGBA,
13
+ THEME_IDS,
14
+ type ThemeId,
15
+ type ThemeMode,
16
+ TUI_COLOR_TOKENS,
17
+ TUI_THEMES,
18
+ type TuiColorToken,
19
+ type TuiColorValue,
20
+ type TuiShikiOptions,
21
+ type TuiThemeJson,
22
+ tuiThemeToShiki,
23
+ } from './tui'
24
+
24
25
  export { GroupBuilder, KeymapBuilder, ModeBindingBuilder } from './keymap-builder'
25
26
  export { getDefaultKeymapConfig } from './defaults'
26
27
  export { resolveConfig } from './resolver'
@@ -28,15 +29,11 @@ export { isAutoCommitEnabled, setAutoCommitEnabled } from './auto-commit-runtime
28
29
  export { getMultiRepoConfig, setMultiRepoConfig } from './multi-repo-runtime'
29
30
  export { DEFAULT_MULTI_REPO_CONFIG } from './defaults'
30
31
 
31
- // Type exports
32
+ // User-facing config types (keymap/backends/sessions/etc.).
32
33
  export type {
33
- // Action types
34
34
  Action,
35
35
  ActionFn,
36
- AimuxPalette,
37
- AimuxTheme,
38
36
  AimuxThemeConfig,
39
- // User-facing config
40
37
  AimuxUserConfig,
41
38
  AIUsageTool,
42
39
  AIUsageToolConfig,
@@ -57,20 +54,16 @@ export type {
57
54
  GroupBuilderApi,
58
55
  HooksConfig,
59
56
  KeyInput,
60
- // Keymap builder API (type surface)
61
57
  KeymapBuilderApi,
62
58
  KeyResult,
63
- // Layout
64
59
  LayoutNode,
65
60
  ModalState,
66
61
  ModeBindingBuilderApi,
67
62
  ModeContext,
68
- // Mode / state
69
63
  ModeId,
70
64
  ModeKeymapDef,
71
65
  MultiRepoConfig,
72
66
  MultiRepoState,
73
- // Resolved config (internal, but exported for tooling)
74
67
  ResolvedConfig,
75
68
  ResolvedKeymapConfig,
76
69
  SessionRecord,
@@ -81,7 +74,4 @@ export type {
81
74
  SplitDirection,
82
75
  StatusBarConfig,
83
76
  TabSession,
84
- Theme,
85
- ThemeId,
86
- ThemeMode,
87
77
  } from './types'
package/src/resolver.ts CHANGED
@@ -51,8 +51,8 @@ export function resolveConfig(userConfig: AimuxUserConfig): ResolvedConfig {
51
51
  function resolveTheme(userConfig: AimuxUserConfig['theme']): ResolvedConfig['theme'] {
52
52
  if (!userConfig) return undefined
53
53
  return {
54
+ initialId: userConfig.initialId,
54
55
  initialMode: userConfig.initialMode ?? userConfig.mode,
55
- paletteOverrides: userConfig.paletteOverrides,
56
56
  }
57
57
  }
58
58
 
@@ -0,0 +1,5 @@
1
+ export { isKnownThemeId, migrateThemeId, THEME_IDS, type ThemeId, TUI_THEMES } from './registry'
2
+ export { resolveTuiTheme } from './resolve'
3
+ export { type TuiShikiOptions, tuiThemeToShiki } from './shiki'
4
+ export { TUI_COLOR_TOKENS, type TuiColorToken } from './tokens'
5
+ export type { ResolvedTuiTheme, RGBA, ThemeMode, TuiColorValue, TuiThemeJson } from './types'
@@ -0,0 +1,95 @@
1
+ // Static registry of every TUI theme JSON shipped with aimux. Generated by
2
+ // hand: re-run after `bun scripts/import-opencode-tui-themes.ts` if upstream
3
+ // adds/removes themes.
4
+
5
+ import type { TuiThemeJson } from './types'
6
+
7
+ import aimux from './themes/aimux.json'
8
+ import aura from './themes/aura.json'
9
+ import ayu from './themes/ayu.json'
10
+ import carbonfox from './themes/carbonfox.json'
11
+ import catppuccinFrappe from './themes/catppuccin-frappe.json'
12
+ import catppuccinMacchiato from './themes/catppuccin-macchiato.json'
13
+ import catppuccin from './themes/catppuccin.json'
14
+ import cobalt2 from './themes/cobalt2.json'
15
+ import cursor from './themes/cursor.json'
16
+ import dracula from './themes/dracula.json'
17
+ import everforest from './themes/everforest.json'
18
+ import flexoki from './themes/flexoki.json'
19
+ import github from './themes/github.json'
20
+ import gruvbox from './themes/gruvbox.json'
21
+ import kanagawa from './themes/kanagawa.json'
22
+ import lucentOrng from './themes/lucent-orng.json'
23
+ import material from './themes/material.json'
24
+ import matrix from './themes/matrix.json'
25
+ import mercury from './themes/mercury.json'
26
+ import monokai from './themes/monokai.json'
27
+ import nightowl from './themes/nightowl.json'
28
+ import nord from './themes/nord.json'
29
+ import oneDark from './themes/one-dark.json'
30
+ import opencode from './themes/opencode.json'
31
+ import orng from './themes/orng.json'
32
+ import osakaJade from './themes/osaka-jade.json'
33
+ import palenight from './themes/palenight.json'
34
+ import rosepine from './themes/rosepine.json'
35
+ import solarized from './themes/solarized.json'
36
+ import synthwave84 from './themes/synthwave84.json'
37
+ import tokyonight from './themes/tokyonight.json'
38
+ import vercel from './themes/vercel.json'
39
+ import vesper from './themes/vesper.json'
40
+ import zenburn from './themes/zenburn.json'
41
+
42
+ export const TUI_THEMES: Record<string, TuiThemeJson> = {
43
+ 'aimux': aimux as TuiThemeJson,
44
+ 'aura': aura as TuiThemeJson,
45
+ 'ayu': ayu as TuiThemeJson,
46
+ 'carbonfox': carbonfox as TuiThemeJson,
47
+ 'catppuccin': catppuccin as TuiThemeJson,
48
+ 'catppuccin-frappe': catppuccinFrappe as TuiThemeJson,
49
+ 'catppuccin-macchiato': catppuccinMacchiato as TuiThemeJson,
50
+ 'cobalt2': cobalt2 as TuiThemeJson,
51
+ 'cursor': cursor as TuiThemeJson,
52
+ 'dracula': dracula as TuiThemeJson,
53
+ 'everforest': everforest as TuiThemeJson,
54
+ 'flexoki': flexoki as TuiThemeJson,
55
+ 'github': github as TuiThemeJson,
56
+ 'gruvbox': gruvbox as TuiThemeJson,
57
+ 'kanagawa': kanagawa as TuiThemeJson,
58
+ 'lucent-orng': lucentOrng as TuiThemeJson,
59
+ 'material': material as TuiThemeJson,
60
+ 'matrix': matrix as TuiThemeJson,
61
+ 'mercury': mercury as TuiThemeJson,
62
+ 'monokai': monokai as TuiThemeJson,
63
+ 'nightowl': nightowl as TuiThemeJson,
64
+ 'nord': nord as TuiThemeJson,
65
+ 'one-dark': oneDark as TuiThemeJson,
66
+ 'opencode': opencode as TuiThemeJson,
67
+ 'orng': orng as TuiThemeJson,
68
+ 'osaka-jade': osakaJade as TuiThemeJson,
69
+ 'palenight': palenight as TuiThemeJson,
70
+ 'rosepine': rosepine as TuiThemeJson,
71
+ 'solarized': solarized as TuiThemeJson,
72
+ 'synthwave84': synthwave84 as TuiThemeJson,
73
+ 'tokyonight': tokyonight as TuiThemeJson,
74
+ 'vercel': vercel as TuiThemeJson,
75
+ 'vesper': vesper as TuiThemeJson,
76
+ 'zenburn': zenburn as TuiThemeJson,
77
+ }
78
+
79
+ export type ThemeId = keyof typeof TUI_THEMES & string
80
+
81
+ export const THEME_IDS: ThemeId[] = Object.keys(TUI_THEMES).sort() as ThemeId[]
82
+
83
+ export function isKnownThemeId(id: string): id is ThemeId {
84
+ return id in TUI_THEMES
85
+ }
86
+
87
+ const LEGACY_ID_MAP: Record<string, ThemeId> = {
88
+ 'aimux-dark': 'aimux',
89
+ 'aimux-light': 'aimux',
90
+ }
91
+
92
+ export function migrateThemeId(id: string): ThemeId {
93
+ if (isKnownThemeId(id)) return id
94
+ return LEGACY_ID_MAP[id] ?? 'aimux'
95
+ }
@@ -0,0 +1,156 @@
1
+ // Port of opencode TUI's resolveTheme + ansiToRgba.
2
+ // Source: opencode/packages/opencode/src/cli/cmd/tui/context/theme.tsx:198-301
3
+ // (pinned reference). Behavior preserved verbatim; output uses CSS-style color
4
+ // strings (hex / rgba) so values flow directly into opentui without conversion.
5
+
6
+ import type { ResolvedTuiTheme, RGBA, ThemeMode, TuiColorValue, TuiThemeJson } from './types'
7
+
8
+ import { TUI_COLOR_TOKENS, type TuiColorToken } from './tokens'
9
+
10
+ const TRANSPARENT: RGBA = { a: 0, b: 0, g: 0, r: 0 }
11
+
12
+ function rgbaFromHex(hex: string): RGBA {
13
+ const h = hex.replace('#', '')
14
+ // expand short forms (#rgb, #rgba)
15
+ const expanded =
16
+ h.length === 3 || h.length === 4
17
+ ? h
18
+ .split('')
19
+ .map((c) => c + c)
20
+ .join('')
21
+ : h
22
+ if (expanded.length === 6) {
23
+ const num = parseInt(expanded, 16)
24
+ return {
25
+ a: 255,
26
+ b: num & 0xff,
27
+ g: (num >> 8) & 0xff,
28
+ r: (num >> 16) & 0xff,
29
+ }
30
+ }
31
+ if (expanded.length === 8) {
32
+ const num = parseInt(expanded, 16) >>> 0
33
+ return {
34
+ a: num & 0xff,
35
+ b: (num >> 8) & 0xff,
36
+ g: (num >> 16) & 0xff,
37
+ r: (num >> 24) & 0xff,
38
+ }
39
+ }
40
+ return { a: 255, b: 0, g: 0, r: 0 }
41
+ }
42
+
43
+ function ansiToRgba(code: number): RGBA {
44
+ if (code < 16) {
45
+ const ansiColors = [
46
+ '#000000', // Black
47
+ '#800000', // Red
48
+ '#008000', // Green
49
+ '#808000', // Yellow
50
+ '#000080', // Blue
51
+ '#800080', // Magenta
52
+ '#008080', // Cyan
53
+ '#c0c0c0', // White
54
+ '#808080', // Bright Black
55
+ '#ff0000', // Bright Red
56
+ '#00ff00', // Bright Green
57
+ '#ffff00', // Bright Yellow
58
+ '#0000ff', // Bright Blue
59
+ '#ff00ff', // Bright Magenta
60
+ '#00ffff', // Bright Cyan
61
+ '#ffffff', // Bright White
62
+ ]
63
+ return rgbaFromHex(ansiColors[code] ?? '#000000')
64
+ }
65
+ if (code < 232) {
66
+ const index = code - 16
67
+ const b = index % 6
68
+ const g = Math.floor(index / 6) % 6
69
+ const r = Math.floor(index / 36)
70
+ const val = (x: number) => (x === 0 ? 0 : x * 40 + 55)
71
+ return { a: 255, b: val(b), g: val(g), r: val(r) }
72
+ }
73
+ if (code < 256) {
74
+ const gray = (code - 232) * 10 + 8
75
+ return { a: 255, b: gray, g: gray, r: gray }
76
+ }
77
+ return { a: 255, b: 0, g: 0, r: 0 }
78
+ }
79
+
80
+ /** Recursive color resolver. Mirrors opencode TUI `resolveColor`. */
81
+ function resolveColorRgba(
82
+ c: TuiColorValue,
83
+ theme: TuiThemeJson,
84
+ mode: ThemeMode,
85
+ chain: string[] = []
86
+ ): RGBA {
87
+ if (typeof c === 'string') {
88
+ if (c === 'transparent' || c === 'none') return TRANSPARENT
89
+ if (c.startsWith('#')) return rgbaFromHex(c)
90
+ if (chain.includes(c)) {
91
+ throw new Error(`Circular color reference: ${[...chain, c].join(' -> ')}`)
92
+ }
93
+ const defs = theme.defs ?? {}
94
+ const next = defs[c] ?? (theme.theme as Record<string, TuiColorValue>)[c]
95
+ if (next === undefined) {
96
+ throw new Error(`Color reference "${c}" not found in defs or theme`)
97
+ }
98
+ return resolveColorRgba(next, theme, mode, [...chain, c])
99
+ }
100
+ if (typeof c === 'number') return ansiToRgba(c)
101
+ return resolveColorRgba(c[mode], theme, mode, chain)
102
+ }
103
+
104
+ function rgbaToCss(c: RGBA): string {
105
+ const r = Math.max(0, Math.min(255, Math.round(c.r)))
106
+ const g = Math.max(0, Math.min(255, Math.round(c.g)))
107
+ const b = Math.max(0, Math.min(255, Math.round(c.b)))
108
+ const a = Math.max(0, Math.min(255, Math.round(c.a)))
109
+ if (a === 255) {
110
+ const hex = (v: number) => v.toString(16).padStart(2, '0')
111
+ return `#${hex(r)}${hex(g)}${hex(b)}`
112
+ }
113
+ return `rgba(${r}, ${g}, ${b}, ${(a / 255).toFixed(3)})`
114
+ }
115
+
116
+ /**
117
+ * Resolve a TUI theme JSON to a flat record of CSS color strings.
118
+ * @param mode "dark" or "light" — selects between {dark, light} branches in token values.
119
+ */
120
+ export function resolveTuiTheme(theme: TuiThemeJson, mode: ThemeMode): ResolvedTuiTheme {
121
+ const out: Partial<Record<TuiColorToken, string>> = {}
122
+
123
+ // Pass 1: every token defined in the JSON, except optional/derived ones.
124
+ for (const [key, value] of Object.entries(theme.theme)) {
125
+ if (key === 'selectedListItemText' || key === 'backgroundMenu' || key === 'thinkingOpacity')
126
+ continue
127
+ out[key as TuiColorToken] = rgbaToCss(resolveColorRgba(value as TuiColorValue, theme, mode))
128
+ }
129
+
130
+ // Pass 2: fallbacks (matches opencode behavior).
131
+ if (theme.theme.selectedListItemText !== undefined) {
132
+ out.selectedListItemText = rgbaToCss(
133
+ resolveColorRgba(theme.theme.selectedListItemText, theme, mode)
134
+ )
135
+ } else if (out.background !== undefined) {
136
+ out.selectedListItemText = out.background
137
+ }
138
+
139
+ if (theme.theme.backgroundMenu !== undefined) {
140
+ out.backgroundMenu = rgbaToCss(resolveColorRgba(theme.theme.backgroundMenu, theme, mode))
141
+ } else if (out.backgroundElement !== undefined) {
142
+ out.backgroundMenu = out.backgroundElement
143
+ }
144
+
145
+ // Sanity: every token should be present. Any missing token in a JSON falls
146
+ // back to text (foreground) so we never hand an `undefined` to opentui.
147
+ const fallback = out.text ?? out.background ?? '#000000'
148
+ for (const tok of TUI_COLOR_TOKENS) {
149
+ if (out[tok] === undefined) out[tok] = fallback
150
+ }
151
+
152
+ return {
153
+ ...(out as Record<TuiColorToken, string>),
154
+ thinkingOpacity: theme.theme.thinkingOpacity ?? 0.6,
155
+ }
156
+ }
@@ -0,0 +1,149 @@
1
+ // Build a Shiki ThemeRegistrationRaw from a resolved TUI theme.
2
+
3
+ import type { ThemeRegistrationRaw } from 'shiki'
4
+
5
+ import type { ResolvedTuiTheme, ThemeMode } from './types'
6
+
7
+ export interface TuiShikiOptions {
8
+ name: string
9
+ mode: ThemeMode
10
+ theme: ResolvedTuiTheme
11
+ }
12
+
13
+ export function tuiThemeToShiki(opts: TuiShikiOptions): ThemeRegistrationRaw {
14
+ const { mode, name, theme: t } = opts
15
+ const bg = t.background
16
+ const fg = t.text
17
+
18
+ return {
19
+ bg,
20
+ colors: { 'editor.background': bg, 'editor.foreground': fg },
21
+ fg,
22
+ name,
23
+ settings: [
24
+ { settings: { background: bg, foreground: fg } },
25
+ {
26
+ scope: ['comment', 'punctuation.definition.comment', 'comment.documentation'],
27
+ settings: { fontStyle: 'italic', foreground: t.syntaxComment },
28
+ },
29
+ {
30
+ scope: ['string', 'string.quoted', 'string.template'],
31
+ settings: { foreground: t.syntaxString },
32
+ },
33
+ {
34
+ scope: ['string.regexp', 'string.escape', 'constant.character.escape'],
35
+ settings: { foreground: t.syntaxString },
36
+ },
37
+ {
38
+ scope: [
39
+ 'constant.numeric',
40
+ 'constant.language',
41
+ 'constant.language.boolean',
42
+ 'constant.character',
43
+ 'constant.other',
44
+ 'support.constant',
45
+ ],
46
+ settings: { foreground: t.syntaxNumber },
47
+ },
48
+ {
49
+ scope: [
50
+ 'keyword',
51
+ 'keyword.control',
52
+ 'keyword.operator.new',
53
+ 'keyword.other',
54
+ 'storage',
55
+ 'storage.type',
56
+ 'storage.modifier',
57
+ ],
58
+ settings: { fontStyle: 'bold', foreground: t.syntaxKeyword },
59
+ },
60
+ {
61
+ scope: ['keyword.operator', 'meta.brace', 'punctuation.separator'],
62
+ settings: { foreground: t.syntaxOperator },
63
+ },
64
+ {
65
+ scope: ['punctuation', 'punctuation.section'],
66
+ settings: { foreground: t.syntaxPunctuation },
67
+ },
68
+ {
69
+ scope: [
70
+ 'entity.name.function',
71
+ 'support.function',
72
+ 'meta.function-call',
73
+ 'entity.name.function.member',
74
+ ],
75
+ settings: { foreground: t.syntaxFunction },
76
+ },
77
+ {
78
+ scope: [
79
+ 'entity.name.type',
80
+ 'support.type',
81
+ 'support.class',
82
+ 'entity.name.class',
83
+ 'entity.name.interface',
84
+ 'entity.name.namespace',
85
+ 'entity.name.type.enum',
86
+ 'entity.name.type.alias',
87
+ 'entity.name.tag.jsx',
88
+ 'support.class.component',
89
+ ],
90
+ settings: { fontStyle: 'italic', foreground: t.syntaxType },
91
+ },
92
+ {
93
+ scope: ['variable', 'meta.variable'],
94
+ settings: { foreground: t.syntaxVariable },
95
+ },
96
+ {
97
+ scope: ['variable.parameter', 'meta.function.parameters'],
98
+ settings: { fontStyle: 'italic', foreground: t.syntaxVariable },
99
+ },
100
+ {
101
+ scope: ['variable.other.property', 'variable.other.member', 'meta.object-literal.key'],
102
+ settings: { foreground: t.syntaxVariable },
103
+ },
104
+ {
105
+ scope: ['variable.language', 'variable.language.this'],
106
+ settings: { fontStyle: 'italic', foreground: t.syntaxNumber },
107
+ },
108
+ { scope: ['entity.name.tag', 'meta.tag'], settings: { foreground: t.error } },
109
+ {
110
+ scope: ['entity.other.attribute-name'],
111
+ settings: { fontStyle: 'italic', foreground: t.warning },
112
+ },
113
+ // Markdown
114
+ {
115
+ scope: ['markup.heading'],
116
+ settings: { fontStyle: 'bold', foreground: t.markdownHeading },
117
+ },
118
+ {
119
+ scope: ['markup.bold'],
120
+ settings: { fontStyle: 'bold', foreground: t.markdownStrong },
121
+ },
122
+ {
123
+ scope: ['markup.italic'],
124
+ settings: { fontStyle: 'italic', foreground: t.markdownEmph },
125
+ },
126
+ {
127
+ scope: ['markup.underline.link', 'markup.inline.raw', 'markup.raw'],
128
+ settings: { foreground: t.markdownCode },
129
+ },
130
+ { scope: ['markup.list'], settings: { foreground: t.markdownListItem } },
131
+ {
132
+ scope: ['markup.quote'],
133
+ settings: { fontStyle: 'italic', foreground: t.markdownBlockQuote },
134
+ },
135
+ // Diff
136
+ {
137
+ scope: ['markup.inserted', 'meta.diff.header.to-file'],
138
+ settings: { foreground: t.diffAdded },
139
+ },
140
+ {
141
+ scope: ['markup.deleted', 'meta.diff.header.from-file'],
142
+ settings: { foreground: t.diffRemoved },
143
+ },
144
+ { scope: ['markup.changed'], settings: { foreground: t.warning } },
145
+ { scope: ['meta.diff.range'], settings: { foreground: t.diffHunkHeader } },
146
+ ],
147
+ type: mode,
148
+ }
149
+ }