@fresh-editor/fresh-editor 0.1.74 → 0.1.76

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 (41) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +6 -0
  3. package/package.json +1 -1
  4. package/plugins/audit_mode.ts +9 -4
  5. package/plugins/buffer_modified.ts +1 -1
  6. package/plugins/calculator.ts +1 -1
  7. package/plugins/check-types.sh +41 -0
  8. package/plugins/clangd_support.ts +1 -1
  9. package/plugins/color_highlighter.ts +4 -1
  10. package/plugins/config-schema.json +44 -2
  11. package/plugins/diagnostics_panel.i18n.json +52 -52
  12. package/plugins/diagnostics_panel.ts +168 -540
  13. package/plugins/find_references.ts +82 -324
  14. package/plugins/git_blame.i18n.json +260 -247
  15. package/plugins/git_blame.ts +4 -9
  16. package/plugins/git_find_file.ts +42 -270
  17. package/plugins/git_grep.ts +50 -167
  18. package/plugins/git_gutter.ts +1 -1
  19. package/plugins/git_log.ts +4 -11
  20. package/plugins/lib/finder.ts +1499 -0
  21. package/plugins/lib/fresh.d.ts +104 -19
  22. package/plugins/lib/index.ts +14 -0
  23. package/plugins/lib/navigation-controller.ts +1 -1
  24. package/plugins/lib/panel-manager.ts +7 -13
  25. package/plugins/lib/results-panel.ts +914 -0
  26. package/plugins/lib/search-utils.ts +343 -0
  27. package/plugins/lib/virtual-buffer-factory.ts +3 -2
  28. package/plugins/live_grep.ts +56 -379
  29. package/plugins/markdown_compose.ts +1 -17
  30. package/plugins/merge_conflict.ts +16 -14
  31. package/plugins/path_complete.ts +1 -1
  32. package/plugins/search_replace.i18n.json +13 -13
  33. package/plugins/search_replace.ts +11 -9
  34. package/plugins/theme_editor.ts +57 -30
  35. package/plugins/todo_highlighter.ts +1 -0
  36. package/plugins/vi_mode.ts +9 -5
  37. package/plugins/welcome.ts +1 -1
  38. package/themes/dark.json +102 -0
  39. package/themes/high-contrast.json +102 -0
  40. package/themes/light.json +102 -0
  41. package/themes/nostalgia.json +102 -0
@@ -28,7 +28,7 @@
28
28
  "panel.results": "Results: {count}",
29
29
  "panel.limited": "(limited to {max})",
30
30
  "panel.selected": "({selected} selected)",
31
- "panel.help": "[SPC] toggle [a] all [n] none [r] REPLACE [RET] preview [q] close"
31
+ "panel.help": "[Up/Down] navigate [Space] toggle [Enter] replace [Esc] close"
32
32
  },
33
33
  "cs": {
34
34
  "cmd.search_replace": "Hledat a nahradit v projektu",
@@ -59,7 +59,7 @@
59
59
  "panel.results": "Vysledky: {count}",
60
60
  "panel.limited": "(omezeno na {max})",
61
61
  "panel.selected": "({selected} vybrano)",
62
- "panel.help": "[MEZERNIK] prepnout [a] vse [n] nic [r] NAHRADIT [ENTER] nahled [q] zavrit"
62
+ "panel.help": "[Nahoru/Dolu] navigace [Mezernik] prepnout [Enter] nahradit [Esc] zavrit"
63
63
  },
64
64
  "de": {
65
65
  "cmd.search_replace": "Suchen und Ersetzen im Projekt",
@@ -90,7 +90,7 @@
90
90
  "panel.results": "Ergebnisse: {count}",
91
91
  "panel.limited": "(begrenzt auf {max})",
92
92
  "panel.selected": "({selected} ausgewaehlt)",
93
- "panel.help": "[LEER] umschalten [a] alle [n] keine [r] ERSETZEN [RET] Vorschau [q] schliessen"
93
+ "panel.help": "[Auf/Ab] navigieren [Leer] umschalten [Enter] ersetzen [Esc] schliessen"
94
94
  },
95
95
  "es": {
96
96
  "cmd.search_replace": "Buscar y Reemplazar en Proyecto",
@@ -121,7 +121,7 @@
121
121
  "panel.results": "Resultados: {count}",
122
122
  "panel.limited": "(limitado a {max})",
123
123
  "panel.selected": "({selected} seleccionados)",
124
- "panel.help": "[ESP] alternar [a] todos [n] ninguno [r] REEMPLAZAR [RET] vista previa [q] cerrar"
124
+ "panel.help": "[Arriba/Abajo] navegar [Espacio] alternar [Enter] reemplazar [Esc] cerrar"
125
125
  },
126
126
  "fr": {
127
127
  "cmd.search_replace": "Rechercher et Remplacer dans le Projet",
@@ -152,7 +152,7 @@
152
152
  "panel.results": "Resultats : {count}",
153
153
  "panel.limited": "(limite a {max})",
154
154
  "panel.selected": "({selected} selectionnes)",
155
- "panel.help": "[ESP] basculer [a] tous [n] aucun [r] REMPLACER [RET] apercu [q] fermer"
155
+ "panel.help": "[Haut/Bas] naviguer [Espace] basculer [Entree] remplacer [Esc] fermer"
156
156
  },
157
157
  "it": {
158
158
  "cmd.search_replace": "Cerca e sostituisci nel progetto",
@@ -183,7 +183,7 @@
183
183
  "panel.results": "Risultati: {count}",
184
184
  "panel.limited": "(limitati a {max})",
185
185
  "panel.selected": "({selected} selezionati)",
186
- "panel.help": "[SPZ] alterna [a] tutti [n] nessuno [r] SOSTITUISCI [RET] anteprima [q] chiudi"
186
+ "panel.help": "[Su/Giu] naviga [Spazio] alterna [Invio] sostituisci [Esc] chiudi"
187
187
  },
188
188
  "ja": {
189
189
  "cmd.search_replace": "プロジェクト内で検索と置換",
@@ -214,7 +214,7 @@
214
214
  "panel.results": "結果: {count}",
215
215
  "panel.limited": "(最大 {max} 件)",
216
216
  "panel.selected": "({selected} 件選択)",
217
- "panel.help": "[スペース] 切替 [a] 全選択 [n] 全解除 [r] 置換 [RET] プレビュー [q] 閉じる"
217
+ "panel.help": "[上/下] 移動 [スペース] 切替 [Enter] 置換 [Esc] 閉じる"
218
218
  },
219
219
  "ko": {
220
220
  "cmd.search_replace": "프로젝트에서 검색 및 바꾸기",
@@ -245,7 +245,7 @@
245
245
  "panel.results": "결과: {count}",
246
246
  "panel.limited": "(최대 {max}개)",
247
247
  "panel.selected": "({selected}개 선택)",
248
- "panel.help": "[스페이스] 전환 [a] 전체 [n] 없음 [r] 바꾸기 [엔터] 미리보기 [q] 닫기"
248
+ "panel.help": "[위/아래] 탐색 [스페이스] 전환 [엔터] 바꾸기 [Esc] 닫기"
249
249
  },
250
250
  "pt-BR": {
251
251
  "cmd.search_replace": "Pesquisar e Substituir no Projeto",
@@ -276,7 +276,7 @@
276
276
  "panel.results": "Resultados: {count}",
277
277
  "panel.limited": "(limitado a {max})",
278
278
  "panel.selected": "({selected} selecionados)",
279
- "panel.help": "[ESP] alternar [a] todos [n] nenhum [r] SUBSTITUIR [ENTER] visualizar [q] fechar"
279
+ "panel.help": "[Cima/Baixo] navegar [Espaco] alternar [Enter] substituir [Esc] fechar"
280
280
  },
281
281
  "ru": {
282
282
  "cmd.search_replace": "Поиск и замена в проекте",
@@ -307,7 +307,7 @@
307
307
  "panel.results": "Результаты: {count}",
308
308
  "panel.limited": "(ограничено до {max})",
309
309
  "panel.selected": "({selected} выбрано)",
310
- "panel.help": "[ПРОБЕЛ] переключить [a] все [n] ничего [r] ЗАМЕНИТЬ [ВВОД] просмотр [q] закрыть"
310
+ "panel.help": "[Вверх/Вниз] навигация [Пробел] переключить [Enter] заменить [Esc] закрыть"
311
311
  },
312
312
  "th": {
313
313
  "cmd.search_replace": "ค้นหาและแทนที่ในโปรเจกต์",
@@ -338,7 +338,7 @@
338
338
  "panel.results": "ผลลัพธ์: {count}",
339
339
  "panel.limited": "(จำกัด {max})",
340
340
  "panel.selected": "(เลือก {selected})",
341
- "panel.help": "[เว้นวรรค] สลับ [a] ทั้งหมด [n] ไม่มี [r] แทนที่ [ENTER] ดูตัวอย่าง [q] ปิด"
341
+ "panel.help": "[ขึ้น/ลง] นำทาง [เว้นวรรค] สลับ [Enter] แทนที่ [Esc] ปิด"
342
342
  },
343
343
  "uk": {
344
344
  "cmd.search_replace": "Пошук та заміна в проекті",
@@ -369,7 +369,7 @@
369
369
  "panel.results": "Результати: {count}",
370
370
  "panel.limited": "(обмежено до {max})",
371
371
  "panel.selected": "({selected} вибрано)",
372
- "panel.help": "[ПРОБІЛ] перемкнути [a] всі [n] нічого [r] ЗАМІНИТИ [ВВІД] перегляд [q] закрити"
372
+ "panel.help": "[Вгору/Вниз] навігація [Пробіл] перемкнути [Enter] замінити [Esc] закрити"
373
373
  },
374
374
  "zh-CN": {
375
375
  "cmd.search_replace": "在项目中搜索和替换",
@@ -400,6 +400,6 @@
400
400
  "panel.results": "结果: {count}",
401
401
  "panel.limited": "(限制为 {max})",
402
402
  "panel.selected": "(已选择 {selected})",
403
- "panel.help": "[空格] 切换 [a] 全选 [n] 全不选 [r] 替换 [回车] 预览 [q] 关闭"
403
+ "panel.help": "[上/下] 导航 [空格] 切换 [回车] 替换 [Esc] 关闭"
404
404
  }
405
405
  }
@@ -1,4 +1,4 @@
1
- /// <reference path="../types/fresh.d.ts" />
1
+ /// <reference path="./lib/fresh.d.ts" />
2
2
  const editor = getEditor();
3
3
 
4
4
 
@@ -32,16 +32,17 @@ let searchRegex: boolean = false;
32
32
  const MAX_RESULTS = 200;
33
33
 
34
34
  // Define the search-replace mode with keybindings
35
+ // Inherits from "normal" for cursor navigation (Up/Down)
36
+ // Simplified keybindings following UX best practices:
37
+ // - Enter: Execute replace (primary action)
38
+ // - Space: Toggle selection
39
+ // - Escape: Close panel
35
40
  editor.defineMode(
36
41
  "search-replace-list",
37
- null,
42
+ "normal", // Inherit from normal for cursor movement
38
43
  [
39
- ["Return", "search_replace_preview"],
44
+ ["Return", "search_replace_execute"],
40
45
  ["space", "search_replace_toggle_item"],
41
- ["a", "search_replace_select_all"],
42
- ["n", "search_replace_select_none"],
43
- ["r", "search_replace_execute"],
44
- ["q", "search_replace_close"],
45
46
  ["Escape", "search_replace_close"],
46
47
  ],
47
48
  true // read-only
@@ -225,7 +226,7 @@ async function showResultsPanel(): Promise<void> {
225
226
  const entries = buildPanelEntries();
226
227
 
227
228
  try {
228
- resultsBufferId = await editor.createVirtualBufferInSplit({
229
+ const result = await editor.createVirtualBufferInSplit({
229
230
  name: "*Search/Replace*",
230
231
  mode: "search-replace-list",
231
232
  read_only: true,
@@ -235,9 +236,10 @@ async function showResultsPanel(): Promise<void> {
235
236
  show_line_numbers: false,
236
237
  show_cursors: true,
237
238
  });
239
+ resultsBufferId = result.buffer_id;
240
+ resultsSplitId = result.split_id ?? editor.getActiveSplitId();
238
241
 
239
242
  panelOpen = true;
240
- resultsSplitId = editor.getActiveSplitId();
241
243
  editor.debug(`Search/Replace panel opened with buffer ID ${resultsBufferId}`);
242
244
  } catch (error) {
243
245
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -1,4 +1,4 @@
1
- /// <reference path="../types/fresh.d.ts" />
1
+ /// <reference path="./lib/fresh.d.ts" />
2
2
  const editor = getEditor();
3
3
 
4
4
 
@@ -12,6 +12,7 @@ const editor = getEditor();
12
12
  * - Copy from built-in themes to use as starting point
13
13
  * - Save as new theme name
14
14
  * - Easy option to set as default theme
15
+ *
15
16
  */
16
17
 
17
18
  // =============================================================================
@@ -108,7 +109,10 @@ function loadThemeSections(): ThemeSection[] {
108
109
  return cachedThemeSections;
109
110
  }
110
111
 
111
- const schema = editor.getThemeSchema();
112
+ const schema = editor.getThemeSchema() as {
113
+ $defs?: Record<string, Record<string, unknown>>;
114
+ properties?: Record<string, unknown>;
115
+ };
112
116
  const defs = schema.$defs || {};
113
117
 
114
118
  // Helper to resolve $ref and get the referenced schema
@@ -197,7 +201,6 @@ function getThemeSections(): ThemeSection[] {
197
201
  // =============================================================================
198
202
 
199
203
  interface ThemeEditorState {
200
- isOpen: boolean;
201
204
  bufferId: number | null;
202
205
  splitId: number | null;
203
206
  sourceSplitId: number | null;
@@ -228,8 +231,33 @@ interface ThemeEditorState {
228
231
  savedCursorPath: string | null;
229
232
  }
230
233
 
234
+ /**
235
+ * Check if the theme editor is currently open.
236
+ * Uses a stateless approach by checking if the buffer actually exists.
237
+ * This handles cases where the buffer was closed externally (e.g., Ctrl+W).
238
+ */
239
+ function isThemeEditorOpen(): boolean {
240
+ if (state.bufferId === null) {
241
+ return false;
242
+ }
243
+ // Check if the buffer actually exists
244
+ const buffers = editor.listBuffers();
245
+ const exists = buffers.some(b => b.id === state.bufferId);
246
+
247
+ // If buffer doesn't exist, reset our stale state
248
+ if (!exists) {
249
+ editor.debug(`Theme editor buffer ${state.bufferId} no longer exists, resetting state`);
250
+ state.bufferId = null;
251
+ state.splitId = null;
252
+ state.themeData = {};
253
+ state.originalThemeData = {};
254
+ state.hasChanges = false;
255
+ }
256
+
257
+ return exists;
258
+ }
259
+
231
260
  const state: ThemeEditorState = {
232
- isOpen: false,
233
261
  bufferId: null,
234
262
  splitId: null,
235
263
  sourceSplitId: null,
@@ -455,29 +483,27 @@ function findThemesDir(): string {
455
483
  * Load list of available built-in themes
456
484
  */
457
485
  async function loadBuiltinThemes(): Promise<string[]> {
458
- const themesDir = findThemesDir();
459
486
  try {
460
- const entries = editor.readDir(themesDir);
461
- return entries
462
- .filter(e => e.is_file && e.name.endsWith(".json"))
463
- .map(e => e.name.replace(".json", ""));
464
- } catch {
465
- return ["dark", "light", "high-contrast", "dracula", "nord", "solarized-dark"];
487
+ const builtinThemes = editor.getBuiltinThemes() as Record<string, string>;
488
+ return Object.keys(builtinThemes);
489
+ } catch (e) {
490
+ editor.debug(`Failed to load built-in themes list: ${e}`);
491
+ throw e;
466
492
  }
467
493
  }
468
494
 
469
495
  /**
470
- * Load a theme file from built-in themes directory
496
+ * Load a theme file from built-in themes
471
497
  */
472
498
  async function loadThemeFile(name: string): Promise<Record<string, unknown> | null> {
473
- const themesDir = findThemesDir();
474
- const themePath = editor.pathJoin(themesDir, `${name}.json`);
475
-
476
499
  try {
477
- const content = await editor.readFile(themePath);
478
- return JSON.parse(content);
479
- } catch {
480
- editor.debug(`Failed to load theme: ${name}`);
500
+ const builtinThemes = editor.getBuiltinThemes() as Record<string, string>;
501
+ if (name in builtinThemes) {
502
+ return JSON.parse(builtinThemes[name]);
503
+ }
504
+ return null;
505
+ } catch (e) {
506
+ editor.debug(`Failed to load theme data for '${name}': ${e}`);
481
507
  return null;
482
508
  }
483
509
  }
@@ -1401,7 +1427,6 @@ globalThis.onThemeEditorBufferClosed = function(data: {
1401
1427
  }): void {
1402
1428
  if (state.bufferId !== null && data.buffer_id === state.bufferId) {
1403
1429
  // Reset state when our buffer is closed
1404
- state.isOpen = false;
1405
1430
  state.bufferId = null;
1406
1431
  state.splitId = null;
1407
1432
  state.themeData = {};
@@ -1617,7 +1642,11 @@ globalThis.theme_editor_nav_prev_section = function(): void {
1617
1642
  * Open the theme editor - prompts user to select theme first
1618
1643
  */
1619
1644
  globalThis.open_theme_editor = async function(): Promise<void> {
1620
- if (state.isOpen) {
1645
+ if (isThemeEditorOpen()) {
1646
+ // Focus the existing theme editor split
1647
+ if (state.splitId !== null) {
1648
+ editor.focusSplit(state.splitId);
1649
+ }
1621
1650
  editor.setStatus(editor.t("status.already_open"));
1622
1651
  return;
1623
1652
  }
@@ -1690,7 +1719,6 @@ async function doOpenThemeEditor(): Promise<void> {
1690
1719
  });
1691
1720
 
1692
1721
  if (bufferId !== null) {
1693
- state.isOpen = true;
1694
1722
  state.bufferId = bufferId;
1695
1723
  state.splitId = null;
1696
1724
 
@@ -1705,7 +1733,7 @@ async function doOpenThemeEditor(): Promise<void> {
1705
1733
  * Close the theme editor
1706
1734
  */
1707
1735
  globalThis.theme_editor_close = function(): void {
1708
- if (!state.isOpen) return;
1736
+ if (!isThemeEditorOpen()) return;
1709
1737
 
1710
1738
  if (state.hasChanges) {
1711
1739
  // Show confirmation prompt before closing with unsaved changes
@@ -1731,7 +1759,6 @@ function doCloseEditor(): void {
1731
1759
  }
1732
1760
 
1733
1761
  // Reset state
1734
- state.isOpen = false;
1735
1762
  state.bufferId = null;
1736
1763
  state.splitId = null;
1737
1764
  state.themeData = {};
@@ -1773,7 +1800,7 @@ globalThis.theme_editor_edit_color = function(): void {
1773
1800
  }
1774
1801
 
1775
1802
  if (field.isSection) {
1776
- theme_editor_toggle_section();
1803
+ globalThis.theme_editor_toggle_section();
1777
1804
  return;
1778
1805
  }
1779
1806
 
@@ -1839,13 +1866,13 @@ globalThis.theme_editor_save = async function(): Promise<void> {
1839
1866
  // Built-in themes require Save As
1840
1867
  if (state.isBuiltin) {
1841
1868
  editor.setStatus(editor.t("status.builtin_requires_save_as"));
1842
- theme_editor_save_as();
1869
+ globalThis.theme_editor_save_as();
1843
1870
  return;
1844
1871
  }
1845
1872
 
1846
1873
  // If theme has never been saved (no path), trigger "Save As" instead
1847
1874
  if (!state.themePath) {
1848
- theme_editor_save_as();
1875
+ globalThis.theme_editor_save_as();
1849
1876
  return;
1850
1877
  }
1851
1878
 
@@ -1980,10 +2007,10 @@ globalThis.onThemeDeletePromptConfirmed = async function(args: {
1980
2007
 
1981
2008
  const value = args.input.trim();
1982
2009
  if (value === "delete" || value === editor.t("prompt.delete_yes")) {
1983
- if (state.themePath) {
2010
+ if (state.themeName) {
1984
2011
  try {
1985
- // Delete the theme file
1986
- await editor.deleteFile(state.themePath);
2012
+ // Delete the theme file by name
2013
+ await editor.deleteTheme(state.themeName);
1987
2014
  const deletedName = state.themeName;
1988
2015
 
1989
2016
  // Reset to default theme
@@ -1,3 +1,4 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
1
2
  // TypeScript TODO Highlighter Plugin
2
3
  // Highlights TODO, FIXME, XXX keywords in source code
3
4
  // Uses targeted overlay invalidation for efficient updates on edits
@@ -12,6 +12,10 @@ const editor = getEditor();
12
12
  *
13
13
  * Uses the plugin API's executeAction() for true operator+motion composability:
14
14
  * any operator works with any motion via O(operators + motions) code.
15
+ *
16
+ * TODO: This plugin uses APIs that don't exist yet:
17
+ * - getLineStartPosition() - for visual block mode column calculation
18
+ * - defineMode with null parent - needs string parent mode
15
19
  */
16
20
 
17
21
  // Vi mode state
@@ -601,7 +605,7 @@ globalThis.vi_repeat = async function (): Promise<void> {
601
605
  editor.executeAction("delete_forward");
602
606
  }
603
607
  if (change.insertedText) {
604
- editor.insertText(change.insertedText);
608
+ editor.insertAtCursor(change.insertedText);
605
609
  }
606
610
  } else if (change.action) {
607
611
  // Simple action like delete_forward, delete_backward
@@ -632,7 +636,7 @@ globalThis.vi_repeat = async function (): Promise<void> {
632
636
  editor.deleteRange(editor.getActiveBufferId(), start, end);
633
637
  }
634
638
  if (change.insertedText) {
635
- editor.insertText(change.insertedText);
639
+ editor.insertAtCursor(change.insertedText);
636
640
  }
637
641
  }
638
642
  break;
@@ -645,7 +649,7 @@ globalThis.vi_repeat = async function (): Promise<void> {
645
649
  // For change: do the delete part, then insert the text
646
650
  applyOperatorWithMotion("d", change.motion, count);
647
651
  if (change.insertedText) {
648
- editor.insertText(change.insertedText);
652
+ editor.insertAtCursor(change.insertedText);
649
653
  }
650
654
  } else {
651
655
  applyOperatorWithMotion(change.operator, change.motion, count);
@@ -662,7 +666,7 @@ globalThis.vi_repeat = async function (): Promise<void> {
662
666
  state.pendingTextObject = change.textObject.modifier;
663
667
  await applyTextObject(change.textObject.object);
664
668
  if (change.operator === "c" && change.insertedText) {
665
- editor.insertText(change.insertedText);
669
+ editor.insertAtCursor(change.insertedText);
666
670
  }
667
671
  }
668
672
  break;
@@ -671,7 +675,7 @@ globalThis.vi_repeat = async function (): Promise<void> {
671
675
  case "insert": {
672
676
  // Pure insert (i, a, o, O)
673
677
  if (change.insertedText) {
674
- editor.insertText(change.insertedText);
678
+ editor.insertAtCursor(change.insertedText);
675
679
  }
676
680
  break;
677
681
  }
@@ -1,4 +1,4 @@
1
- /// <reference path="../types/fresh.d.ts" />
1
+ /// <reference path="./lib/fresh.d.ts" />
2
2
  const editor = getEditor();
3
3
 
4
4
 
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "dark",
3
+ "editor": {
4
+ "bg": [30, 30, 30],
5
+ "fg": [212, 212, 212],
6
+ "cursor": [255, 255, 255],
7
+ "inactive_cursor": [100, 100, 100],
8
+ "selection_bg": [38, 79, 120],
9
+ "current_line_bg": [40, 40, 40],
10
+ "line_number_fg": [100, 100, 100],
11
+ "line_number_bg": [30, 30, 30],
12
+ "diff_add_bg": [35, 60, 35],
13
+ "diff_remove_bg": [70, 35, 35],
14
+ "diff_modify_bg": [40, 38, 30]
15
+ },
16
+ "ui": {
17
+ "tab_active_fg": "Yellow",
18
+ "tab_active_bg": "Blue",
19
+ "tab_inactive_fg": "White",
20
+ "tab_inactive_bg": "DarkGray",
21
+ "tab_separator_bg": [45, 45, 48],
22
+ "tab_close_hover_fg": [255, 100, 100],
23
+ "tab_hover_bg": [70, 70, 75],
24
+ "menu_bg": [60, 60, 65],
25
+ "menu_fg": [220, 220, 220],
26
+ "menu_active_bg": [60, 60, 60],
27
+ "menu_active_fg": [255, 255, 255],
28
+ "menu_dropdown_bg": [50, 50, 50],
29
+ "menu_dropdown_fg": [220, 220, 220],
30
+ "menu_highlight_bg": [70, 130, 180],
31
+ "menu_highlight_fg": [255, 255, 255],
32
+ "menu_border_fg": [100, 100, 100],
33
+ "menu_separator_fg": [80, 80, 80],
34
+ "menu_hover_bg": [55, 55, 55],
35
+ "menu_hover_fg": [255, 255, 255],
36
+ "menu_disabled_fg": [100, 100, 100],
37
+ "menu_disabled_bg": [50, 50, 50],
38
+ "status_bar_fg": "White",
39
+ "status_bar_bg": [30, 30, 30],
40
+ "prompt_fg": "White",
41
+ "prompt_bg": [20, 20, 20],
42
+ "prompt_selection_fg": "White",
43
+ "prompt_selection_bg": [58, 79, 120],
44
+ "popup_border_fg": "Gray",
45
+ "popup_bg": [30, 30, 30],
46
+ "popup_selection_bg": [58, 79, 120],
47
+ "popup_text_fg": "White",
48
+ "suggestion_bg": [30, 30, 30],
49
+ "suggestion_selected_bg": [58, 79, 120],
50
+ "help_bg": "Black",
51
+ "help_fg": "White",
52
+ "help_key_fg": "Cyan",
53
+ "help_separator_fg": "DarkGray",
54
+ "help_indicator_fg": "Red",
55
+ "help_indicator_bg": "Black",
56
+ "inline_code_bg": [60, 60, 60],
57
+ "split_separator_fg": [100, 100, 100],
58
+ "split_separator_hover_fg": [100, 149, 237],
59
+ "scrollbar_track_fg": "DarkGray",
60
+ "scrollbar_thumb_fg": "Gray",
61
+ "scrollbar_track_hover_fg": "Gray",
62
+ "scrollbar_thumb_hover_fg": "White",
63
+ "compose_margin_bg": [18, 18, 18],
64
+ "semantic_highlight_bg": [60, 60, 80],
65
+ "terminal_bg": "Default",
66
+ "terminal_fg": "Default",
67
+ "status_warning_indicator_bg": [181, 137, 0],
68
+ "status_warning_indicator_fg": [0, 0, 0],
69
+ "status_error_indicator_bg": [220, 50, 47],
70
+ "status_error_indicator_fg": [255, 255, 255],
71
+ "status_warning_indicator_hover_bg": [211, 167, 30],
72
+ "status_warning_indicator_hover_fg": [0, 0, 0],
73
+ "status_error_indicator_hover_bg": [250, 80, 77],
74
+ "status_error_indicator_hover_fg": [255, 255, 255],
75
+ "tab_drop_zone_bg": [70, 130, 180],
76
+ "tab_drop_zone_border": [100, 149, 237]
77
+ },
78
+ "search": {
79
+ "match_bg": [100, 100, 20],
80
+ "match_fg": [255, 255, 255]
81
+ },
82
+ "diagnostic": {
83
+ "error_fg": "Red",
84
+ "error_bg": [60, 20, 20],
85
+ "warning_fg": "Yellow",
86
+ "warning_bg": [60, 50, 0],
87
+ "info_fg": "Blue",
88
+ "info_bg": [0, 30, 60],
89
+ "hint_fg": "Gray",
90
+ "hint_bg": [30, 30, 30]
91
+ },
92
+ "syntax": {
93
+ "keyword": [86, 156, 214],
94
+ "string": [206, 145, 120],
95
+ "comment": [106, 153, 85],
96
+ "function": [220, 220, 170],
97
+ "type": [78, 201, 176],
98
+ "variable": [156, 220, 254],
99
+ "constant": [79, 193, 255],
100
+ "operator": [212, 212, 212]
101
+ }
102
+ }
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "high-contrast",
3
+ "editor": {
4
+ "bg": "Black",
5
+ "fg": "White",
6
+ "cursor": "White",
7
+ "inactive_cursor": "DarkGray",
8
+ "selection_bg": [0, 100, 200],
9
+ "current_line_bg": [20, 20, 20],
10
+ "line_number_fg": [140, 140, 140],
11
+ "line_number_bg": "Black",
12
+ "diff_add_bg": [0, 80, 0],
13
+ "diff_remove_bg": [100, 0, 0],
14
+ "diff_modify_bg": [25, 22, 0]
15
+ },
16
+ "ui": {
17
+ "tab_active_fg": "Black",
18
+ "tab_active_bg": "Yellow",
19
+ "tab_inactive_fg": "White",
20
+ "tab_inactive_bg": "Black",
21
+ "tab_separator_bg": [30, 30, 35],
22
+ "tab_close_hover_fg": [249, 38, 114],
23
+ "tab_hover_bg": [50, 50, 55],
24
+ "menu_bg": [50, 50, 55],
25
+ "menu_fg": "White",
26
+ "menu_active_bg": "Yellow",
27
+ "menu_active_fg": "Black",
28
+ "menu_dropdown_bg": [20, 20, 20],
29
+ "menu_dropdown_fg": "White",
30
+ "menu_highlight_bg": [0, 100, 200],
31
+ "menu_highlight_fg": "White",
32
+ "menu_border_fg": "Yellow",
33
+ "menu_separator_fg": "White",
34
+ "menu_hover_bg": [50, 50, 50],
35
+ "menu_hover_fg": "Yellow",
36
+ "menu_disabled_fg": "DarkGray",
37
+ "menu_disabled_bg": [20, 20, 20],
38
+ "status_bar_fg": "White",
39
+ "status_bar_bg": [20, 20, 20],
40
+ "prompt_fg": "White",
41
+ "prompt_bg": [10, 10, 10],
42
+ "prompt_selection_fg": "White",
43
+ "prompt_selection_bg": [0, 100, 200],
44
+ "popup_border_fg": "LightCyan",
45
+ "popup_bg": "Black",
46
+ "popup_selection_bg": [0, 100, 200],
47
+ "popup_text_fg": "White",
48
+ "suggestion_bg": "Black",
49
+ "suggestion_selected_bg": [0, 100, 200],
50
+ "help_bg": "Black",
51
+ "help_fg": "White",
52
+ "help_key_fg": "LightCyan",
53
+ "help_separator_fg": "White",
54
+ "help_indicator_fg": "Red",
55
+ "help_indicator_bg": "Black",
56
+ "inline_code_bg": [40, 40, 40],
57
+ "split_separator_fg": [140, 140, 140],
58
+ "split_separator_hover_fg": "Yellow",
59
+ "scrollbar_track_fg": "White",
60
+ "scrollbar_thumb_fg": "Yellow",
61
+ "scrollbar_track_hover_fg": "Yellow",
62
+ "scrollbar_thumb_hover_fg": "Cyan",
63
+ "compose_margin_bg": [10, 10, 10],
64
+ "semantic_highlight_bg": [0, 60, 100],
65
+ "terminal_bg": "Default",
66
+ "terminal_fg": "Default",
67
+ "status_warning_indicator_bg": "Yellow",
68
+ "status_warning_indicator_fg": "Black",
69
+ "status_error_indicator_bg": "Red",
70
+ "status_error_indicator_fg": "White",
71
+ "status_warning_indicator_hover_bg": "LightYellow",
72
+ "status_warning_indicator_hover_fg": "Black",
73
+ "status_error_indicator_hover_bg": "LightRed",
74
+ "status_error_indicator_hover_fg": "White",
75
+ "tab_drop_zone_bg": [0, 100, 200],
76
+ "tab_drop_zone_border": "Yellow"
77
+ },
78
+ "search": {
79
+ "match_bg": "Yellow",
80
+ "match_fg": "Black"
81
+ },
82
+ "diagnostic": {
83
+ "error_fg": "Red",
84
+ "error_bg": [100, 0, 0],
85
+ "warning_fg": "Yellow",
86
+ "warning_bg": [100, 100, 0],
87
+ "info_fg": "Cyan",
88
+ "info_bg": [0, 50, 100],
89
+ "hint_fg": "White",
90
+ "hint_bg": [50, 50, 50]
91
+ },
92
+ "syntax": {
93
+ "keyword": "Cyan",
94
+ "string": "Green",
95
+ "comment": "Gray",
96
+ "function": "Yellow",
97
+ "type": "Magenta",
98
+ "variable": "White",
99
+ "constant": "LightBlue",
100
+ "operator": "White"
101
+ }
102
+ }