@involvex/fresh-editor 0.1.76 → 0.1.78

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 (90) hide show
  1. package/bin/CHANGELOG.md +1017 -0
  2. package/bin/LICENSE +117 -0
  3. package/bin/README.md +248 -0
  4. package/bin/fresh.exe +0 -0
  5. package/bin/plugins/README.md +71 -0
  6. package/bin/plugins/audit_mode.i18n.json +821 -0
  7. package/bin/plugins/audit_mode.ts +1810 -0
  8. package/bin/plugins/buffer_modified.i18n.json +67 -0
  9. package/bin/plugins/buffer_modified.ts +281 -0
  10. package/bin/plugins/calculator.i18n.json +93 -0
  11. package/bin/plugins/calculator.ts +770 -0
  12. package/bin/plugins/clangd-lsp.ts +168 -0
  13. package/bin/plugins/clangd_support.i18n.json +223 -0
  14. package/bin/plugins/clangd_support.md +20 -0
  15. package/bin/plugins/clangd_support.ts +325 -0
  16. package/bin/plugins/color_highlighter.i18n.json +145 -0
  17. package/bin/plugins/color_highlighter.ts +304 -0
  18. package/bin/plugins/config-schema.json +768 -0
  19. package/bin/plugins/csharp-lsp.ts +147 -0
  20. package/bin/plugins/csharp_support.i18n.json +80 -0
  21. package/bin/plugins/csharp_support.ts +170 -0
  22. package/bin/plugins/css-lsp.ts +143 -0
  23. package/bin/plugins/diagnostics_panel.i18n.json +236 -0
  24. package/bin/plugins/diagnostics_panel.ts +642 -0
  25. package/bin/plugins/examples/README.md +85 -0
  26. package/bin/plugins/examples/async_demo.ts +165 -0
  27. package/bin/plugins/examples/bookmarks.ts +329 -0
  28. package/bin/plugins/examples/buffer_query_demo.ts +110 -0
  29. package/bin/plugins/examples/git_grep.ts +262 -0
  30. package/bin/plugins/examples/hello_world.ts +93 -0
  31. package/bin/plugins/examples/virtual_buffer_demo.ts +116 -0
  32. package/bin/plugins/find_references.i18n.json +275 -0
  33. package/bin/plugins/find_references.ts +359 -0
  34. package/bin/plugins/git_blame.i18n.json +496 -0
  35. package/bin/plugins/git_blame.ts +707 -0
  36. package/bin/plugins/git_find_file.i18n.json +314 -0
  37. package/bin/plugins/git_find_file.ts +300 -0
  38. package/bin/plugins/git_grep.i18n.json +171 -0
  39. package/bin/plugins/git_grep.ts +191 -0
  40. package/bin/plugins/git_gutter.i18n.json +93 -0
  41. package/bin/plugins/git_gutter.ts +477 -0
  42. package/bin/plugins/git_log.i18n.json +481 -0
  43. package/bin/plugins/git_log.ts +1285 -0
  44. package/bin/plugins/go-lsp.ts +143 -0
  45. package/bin/plugins/html-lsp.ts +145 -0
  46. package/bin/plugins/json-lsp.ts +145 -0
  47. package/bin/plugins/lib/fresh.d.ts +1321 -0
  48. package/bin/plugins/lib/index.ts +24 -0
  49. package/bin/plugins/lib/navigation-controller.ts +214 -0
  50. package/bin/plugins/lib/panel-manager.ts +220 -0
  51. package/bin/plugins/lib/types.ts +72 -0
  52. package/bin/plugins/lib/virtual-buffer-factory.ts +130 -0
  53. package/bin/plugins/live_grep.i18n.json +171 -0
  54. package/bin/plugins/live_grep.ts +422 -0
  55. package/bin/plugins/markdown_compose.i18n.json +223 -0
  56. package/bin/plugins/markdown_compose.ts +630 -0
  57. package/bin/plugins/merge_conflict.i18n.json +821 -0
  58. package/bin/plugins/merge_conflict.ts +1810 -0
  59. package/bin/plugins/path_complete.i18n.json +80 -0
  60. package/bin/plugins/path_complete.ts +165 -0
  61. package/bin/plugins/python-lsp.ts +162 -0
  62. package/bin/plugins/rust-lsp.ts +166 -0
  63. package/bin/plugins/search_replace.i18n.json +405 -0
  64. package/bin/plugins/search_replace.ts +484 -0
  65. package/bin/plugins/test_i18n.i18n.json +67 -0
  66. package/bin/plugins/test_i18n.ts +18 -0
  67. package/bin/plugins/theme_editor.i18n.json +3746 -0
  68. package/bin/plugins/theme_editor.ts +2063 -0
  69. package/bin/plugins/todo_highlighter.i18n.json +184 -0
  70. package/bin/plugins/todo_highlighter.ts +206 -0
  71. package/bin/plugins/typescript-lsp.ts +167 -0
  72. package/bin/plugins/vi_mode.i18n.json +1549 -0
  73. package/bin/plugins/vi_mode.ts +2747 -0
  74. package/bin/plugins/welcome.i18n.json +236 -0
  75. package/bin/plugins/welcome.ts +76 -0
  76. package/bin/themes/dark.json +102 -0
  77. package/bin/themes/dracula.json +62 -0
  78. package/bin/themes/high-contrast.json +102 -0
  79. package/bin/themes/light.json +102 -0
  80. package/bin/themes/nord.json +62 -0
  81. package/bin/themes/nostalgia.json +102 -0
  82. package/bin/themes/solarized-dark.json +62 -0
  83. package/binary-install.js +1 -1
  84. package/dist/bin/fresh.js +9 -0
  85. package/dist/binary-install.js +149 -0
  86. package/dist/binary.js +30 -0
  87. package/dist/fresh-6yhknp07.exe +0 -0
  88. package/dist/install.js +158 -0
  89. package/dist/run-fresh.js +43 -0
  90. package/package.json +7 -2
@@ -0,0 +1,184 @@
1
+ {
2
+ "en": {
3
+ "cmd.enable": "TODO Highlighter: Enable",
4
+ "cmd.enable_desc": "Enable TODO keyword highlighting",
5
+ "cmd.disable": "TODO Highlighter: Disable",
6
+ "cmd.disable_desc": "Disable TODO keyword highlighting",
7
+ "cmd.toggle": "TODO Highlighter: Toggle",
8
+ "cmd.toggle_desc": "Toggle TODO keyword highlighting",
9
+ "cmd.show_keywords": "TODO Highlighter: Show Keywords",
10
+ "cmd.show_keywords_desc": "Show currently tracked keywords",
11
+ "status.enabled": "TODO Highlighter: Enabled",
12
+ "status.disabled": "TODO Highlighter: Disabled",
13
+ "status.loaded": "TODO Highlighter plugin loaded (TypeScript)",
14
+ "status.keywords": "TODO Keywords: %{keywords}"
15
+ },
16
+ "cs": {
17
+ "cmd.enable": "TODO zvyraznovac: Povolit",
18
+ "cmd.enable_desc": "Povolit zvyraznovani klicovych slov TODO",
19
+ "cmd.disable": "TODO zvyraznovac: Zakázat",
20
+ "cmd.disable_desc": "Zakazat zvyraznovani klicovych slov TODO",
21
+ "cmd.toggle": "TODO zvyraznovac: Prepnout",
22
+ "cmd.toggle_desc": "Prepnout zvyraznovani klicovych slov TODO",
23
+ "cmd.show_keywords": "TODO zvyraznovac: Zobrazit klicova slova",
24
+ "cmd.show_keywords_desc": "Zobrazit aktualne sledovana klicova slova",
25
+ "status.enabled": "TODO zvyraznovac: Povolen",
26
+ "status.disabled": "TODO zvyraznovac: Zakazan",
27
+ "status.loaded": "Plugin TODO zvyraznovace nacten (TypeScript)",
28
+ "status.keywords": "TODO klicova slova: %{keywords}"
29
+ },
30
+ "de": {
31
+ "cmd.enable": "TODO-Hervorhebung: Aktivieren",
32
+ "cmd.enable_desc": "TODO-Schluesselwort-Hervorhebung aktivieren",
33
+ "cmd.disable": "TODO-Hervorhebung: Deaktivieren",
34
+ "cmd.disable_desc": "TODO-Schluesselwort-Hervorhebung deaktivieren",
35
+ "cmd.toggle": "TODO-Hervorhebung: Umschalten",
36
+ "cmd.toggle_desc": "TODO-Schluesselwort-Hervorhebung umschalten",
37
+ "cmd.show_keywords": "TODO-Hervorhebung: Schluesselwoerter Anzeigen",
38
+ "cmd.show_keywords_desc": "Aktuell verfolgte Schluesselwoerter anzeigen",
39
+ "status.enabled": "TODO-Hervorhebung: Aktiviert",
40
+ "status.disabled": "TODO-Hervorhebung: Deaktiviert",
41
+ "status.loaded": "TODO-Hervorhebung-Plugin geladen (TypeScript)",
42
+ "status.keywords": "TODO-Schluesselwoerter: %{keywords}"
43
+ },
44
+ "es": {
45
+ "cmd.enable": "Resaltador TODO: Activar",
46
+ "cmd.enable_desc": "Activar resaltado de palabras clave TODO",
47
+ "cmd.disable": "Resaltador TODO: Desactivar",
48
+ "cmd.disable_desc": "Desactivar resaltado de palabras clave TODO",
49
+ "cmd.toggle": "Resaltador TODO: Alternar",
50
+ "cmd.toggle_desc": "Alternar resaltado de palabras clave TODO",
51
+ "cmd.show_keywords": "Resaltador TODO: Mostrar Palabras Clave",
52
+ "cmd.show_keywords_desc": "Mostrar palabras clave rastreadas actualmente",
53
+ "status.enabled": "Resaltador TODO: Activado",
54
+ "status.disabled": "Resaltador TODO: Desactivado",
55
+ "status.loaded": "Plugin Resaltador TODO cargado (TypeScript)",
56
+ "status.keywords": "Palabras Clave TODO: %{keywords}"
57
+ },
58
+ "fr": {
59
+ "cmd.enable": "Surligneur TODO: Activer",
60
+ "cmd.enable_desc": "Activer le surlignage des mots-cles TODO",
61
+ "cmd.disable": "Surligneur TODO: Desactiver",
62
+ "cmd.disable_desc": "Desactiver le surlignage des mots-cles TODO",
63
+ "cmd.toggle": "Surligneur TODO: Basculer",
64
+ "cmd.toggle_desc": "Basculer le surlignage des mots-cles TODO",
65
+ "cmd.show_keywords": "Surligneur TODO: Afficher les Mots-cles",
66
+ "cmd.show_keywords_desc": "Afficher les mots-cles actuellement suivis",
67
+ "status.enabled": "Surligneur TODO: Active",
68
+ "status.disabled": "Surligneur TODO: Desactive",
69
+ "status.loaded": "Plugin Surligneur TODO charge (TypeScript)",
70
+ "status.keywords": "Mots-cles TODO: %{keywords}"
71
+ },
72
+ "it": {
73
+ "cmd.enable": "Evidenziatore TODO: Attiva",
74
+ "cmd.enable_desc": "Attiva l'evidenziazione delle parole chiave TODO",
75
+ "cmd.disable": "Evidenziatore TODO: Disattiva",
76
+ "cmd.disable_desc": "Disattiva l'evidenziazione delle parole chiave TODO",
77
+ "cmd.toggle": "Evidenziatore TODO: Alterna",
78
+ "cmd.toggle_desc": "Alterna l'evidenziazione delle parole chiave TODO",
79
+ "cmd.show_keywords": "Evidenziatore TODO: Mostra parole chiave",
80
+ "cmd.show_keywords_desc": "Mostra le parole chiave attualmente monitorate",
81
+ "status.enabled": "Evidenziatore TODO: Attivato",
82
+ "status.disabled": "Evidenziatore TODO: Disattivato",
83
+ "status.loaded": "Plugin Evidenziatore TODO caricato (TypeScript)",
84
+ "status.keywords": "Parole chiave TODO: %{keywords}"
85
+ },
86
+ "ja": {
87
+ "cmd.enable": "TODOハイライター: 有効化",
88
+ "cmd.enable_desc": "TODOキーワードのハイライトを有効化",
89
+ "cmd.disable": "TODOハイライター: 無効化",
90
+ "cmd.disable_desc": "TODOキーワードのハイライトを無効化",
91
+ "cmd.toggle": "TODOハイライター: 切り替え",
92
+ "cmd.toggle_desc": "TODOキーワードのハイライトを切り替え",
93
+ "cmd.show_keywords": "TODOハイライター: キーワード表示",
94
+ "cmd.show_keywords_desc": "現在追跡中のキーワードを表示",
95
+ "status.enabled": "TODOハイライター: 有効",
96
+ "status.disabled": "TODOハイライター: 無効",
97
+ "status.loaded": "TODOハイライタープラグインを読み込みました (TypeScript)",
98
+ "status.keywords": "TODOキーワード: %{keywords}"
99
+ },
100
+ "ko": {
101
+ "cmd.enable": "TODO 하이라이터: 활성화",
102
+ "cmd.enable_desc": "TODO 키워드 강조 표시 활성화",
103
+ "cmd.disable": "TODO 하이라이터: 비활성화",
104
+ "cmd.disable_desc": "TODO 키워드 강조 표시 비활성화",
105
+ "cmd.toggle": "TODO 하이라이터: 전환",
106
+ "cmd.toggle_desc": "TODO 키워드 강조 표시 전환",
107
+ "cmd.show_keywords": "TODO 하이라이터: 키워드 표시",
108
+ "cmd.show_keywords_desc": "현재 추적 중인 키워드 표시",
109
+ "status.enabled": "TODO 하이라이터: 활성화됨",
110
+ "status.disabled": "TODO 하이라이터: 비활성화됨",
111
+ "status.loaded": "TODO 하이라이터 플러그인 로드됨 (TypeScript)",
112
+ "status.keywords": "TODO 키워드: %{keywords}"
113
+ },
114
+ "pt-BR": {
115
+ "cmd.enable": "Realcador TODO: Ativar",
116
+ "cmd.enable_desc": "Ativar realce de palavras-chave TODO",
117
+ "cmd.disable": "Realcador TODO: Desativar",
118
+ "cmd.disable_desc": "Desativar realce de palavras-chave TODO",
119
+ "cmd.toggle": "Realcador TODO: Alternar",
120
+ "cmd.toggle_desc": "Alternar realce de palavras-chave TODO",
121
+ "cmd.show_keywords": "Realcador TODO: Mostrar Palavras-chave",
122
+ "cmd.show_keywords_desc": "Mostrar palavras-chave atualmente rastreadas",
123
+ "status.enabled": "Realcador TODO: Ativado",
124
+ "status.disabled": "Realcador TODO: Desativado",
125
+ "status.loaded": "Plugin Realcador TODO carregado (TypeScript)",
126
+ "status.keywords": "Palavras-chave TODO: %{keywords}"
127
+ },
128
+ "ru": {
129
+ "cmd.enable": "Подсветка TODO: Включить",
130
+ "cmd.enable_desc": "Включить подсветку ключевых слов TODO",
131
+ "cmd.disable": "Подсветка TODO: Выключить",
132
+ "cmd.disable_desc": "Выключить подсветку ключевых слов TODO",
133
+ "cmd.toggle": "Подсветка TODO: Переключить",
134
+ "cmd.toggle_desc": "Переключить подсветку ключевых слов TODO",
135
+ "cmd.show_keywords": "Подсветка TODO: Показать ключевые слова",
136
+ "cmd.show_keywords_desc": "Показать текущие отслеживаемые ключевые слова",
137
+ "status.enabled": "Подсветка TODO: Включена",
138
+ "status.disabled": "Подсветка TODO: Выключена",
139
+ "status.loaded": "Плагин подсветки TODO загружен (TypeScript)",
140
+ "status.keywords": "Ключевые слова TODO: %{keywords}"
141
+ },
142
+ "th": {
143
+ "cmd.enable": "ตัวเน้น TODO: เปิดใช้งาน",
144
+ "cmd.enable_desc": "เปิดใช้งานการเน้นคำสำคัญ TODO",
145
+ "cmd.disable": "ตัวเน้น TODO: ปิดใช้งาน",
146
+ "cmd.disable_desc": "ปิดใช้งานการเน้นคำสำคัญ TODO",
147
+ "cmd.toggle": "ตัวเน้น TODO: สลับ",
148
+ "cmd.toggle_desc": "สลับการเน้นคำสำคัญ TODO",
149
+ "cmd.show_keywords": "ตัวเน้น TODO: แสดงคำสำคัญ",
150
+ "cmd.show_keywords_desc": "แสดงคำสำคัญที่กำลังติดตาม",
151
+ "status.enabled": "ตัวเน้น TODO: เปิดใช้งานแล้ว",
152
+ "status.disabled": "ตัวเน้น TODO: ปิดใช้งานแล้ว",
153
+ "status.loaded": "โหลดปลั๊กอินตัวเน้น TODO แล้ว (TypeScript)",
154
+ "status.keywords": "คำสำคัญ TODO: %{keywords}"
155
+ },
156
+ "uk": {
157
+ "cmd.enable": "Підсвічування TODO: Увімкнути",
158
+ "cmd.enable_desc": "Увімкнути підсвічування ключових слів TODO",
159
+ "cmd.disable": "Підсвічування TODO: Вимкнути",
160
+ "cmd.disable_desc": "Вимкнути підсвічування ключових слів TODO",
161
+ "cmd.toggle": "Підсвічування TODO: Перемкнути",
162
+ "cmd.toggle_desc": "Перемкнути підсвічування ключових слів TODO",
163
+ "cmd.show_keywords": "Підсвічування TODO: Показати ключові слова",
164
+ "cmd.show_keywords_desc": "Показати поточні відстежувані ключові слова",
165
+ "status.enabled": "Підсвічування TODO: Увімкнено",
166
+ "status.disabled": "Підсвічування TODO: Вимкнено",
167
+ "status.loaded": "Плагін підсвічування TODO завантажено (TypeScript)",
168
+ "status.keywords": "Ключові слова TODO: %{keywords}"
169
+ },
170
+ "zh-CN": {
171
+ "cmd.enable": "TODO高亮器: 启用",
172
+ "cmd.enable_desc": "启用TODO关键字高亮显示",
173
+ "cmd.disable": "TODO高亮器: 禁用",
174
+ "cmd.disable_desc": "禁用TODO关键字高亮显示",
175
+ "cmd.toggle": "TODO高亮器: 切换",
176
+ "cmd.toggle_desc": "切换TODO关键字高亮显示",
177
+ "cmd.show_keywords": "TODO高亮器: 显示关键字",
178
+ "cmd.show_keywords_desc": "显示当前跟踪的关键字",
179
+ "status.enabled": "TODO高亮器: 已启用",
180
+ "status.disabled": "TODO高亮器: 已禁用",
181
+ "status.loaded": "TODO高亮器插件已加载 (TypeScript)",
182
+ "status.keywords": "TODO关键字: %{keywords}"
183
+ }
184
+ }
@@ -0,0 +1,206 @@
1
+ // TypeScript TODO Highlighter Plugin
2
+ // Highlights TODO, FIXME, XXX keywords in source code
3
+ // Uses targeted overlay invalidation for efficient updates on edits
4
+ const editor = getEditor();
5
+
6
+
7
+ interface HighlightConfig {
8
+ enabled: boolean;
9
+ keywords: Array<{
10
+ word: string;
11
+ color: [number, number, number];
12
+ }>;
13
+ }
14
+
15
+ // Plugin configuration
16
+ const config: HighlightConfig = {
17
+ enabled: false, // Start disabled, use Enable or Toggle to activate
18
+ keywords: [
19
+ { word: "TODO", color: [255, 200, 50] }, // Yellow
20
+ { word: "FIXME", color: [255, 100, 100] }, // Red
21
+ { word: "XXX", color: [255, 150, 50] }, // Orange
22
+ { word: "HACK", color: [200, 100, 255] }, // Purple
23
+ { word: "NOTE", color: [100, 200, 255] }, // Blue
24
+ ],
25
+ };
26
+
27
+ // Namespace for all TODO highlighter overlays
28
+ const NAMESPACE = "todo";
29
+
30
+ // Process a single line for keyword highlighting
31
+ function highlightLine(
32
+ bufferId: number,
33
+ byteStart: number,
34
+ content: string
35
+ ): void {
36
+ // Search for keywords
37
+ for (const keyword of config.keywords) {
38
+ let searchStart = 0;
39
+ while (true) {
40
+ const pos = content.indexOf(keyword.word, searchStart);
41
+ if (pos === -1) break;
42
+
43
+ // Check if it's a whole word (preceded by non-word char or start)
44
+ const isWordStart = pos === 0 || !/\w/.test(content[pos - 1]);
45
+ const isWordEnd = pos + keyword.word.length >= content.length ||
46
+ !/\w/.test(content[pos + keyword.word.length]);
47
+
48
+ if (isWordStart && isWordEnd) {
49
+ const absoluteStart = byteStart + pos;
50
+ const absoluteEnd = absoluteStart + keyword.word.length;
51
+
52
+ // Add overlay with namespace for efficient batch removal
53
+ editor.addOverlay(
54
+ bufferId,
55
+ NAMESPACE,
56
+ absoluteStart,
57
+ absoluteEnd,
58
+ keyword.color[0],
59
+ keyword.color[1],
60
+ keyword.color[2],
61
+ false // background color, not underline
62
+ );
63
+ }
64
+
65
+ searchStart = pos + 1;
66
+ }
67
+ }
68
+ }
69
+
70
+ // Clear highlights for a buffer using namespace
71
+ function clearHighlights(bufferId: number): void {
72
+ editor.clearNamespace(bufferId, NAMESPACE);
73
+ }
74
+
75
+ // Handle lines_changed events (batched for efficiency)
76
+ // This is called for lines that need (re)processing
77
+ globalThis.onLinesChanged = function(data: {
78
+ buffer_id: number;
79
+ lines: Array<{
80
+ line_number: number;
81
+ byte_start: number;
82
+ byte_end: number;
83
+ content: string;
84
+ }>;
85
+ }): void {
86
+ if (!config.enabled) return;
87
+
88
+ // Process all changed lines and create overlays for them
89
+ for (const line of data.lines) {
90
+ highlightLine(data.buffer_id, line.byte_start, line.content);
91
+ }
92
+ };
93
+
94
+ // Handle buffer content changes - clear only affected overlays
95
+ // The editor will automatically re-send the affected lines via lines_changed
96
+ globalThis.onAfterInsert = function(data: {
97
+ buffer_id: number;
98
+ position: number;
99
+ text: string;
100
+ affected_start: number;
101
+ affected_end: number;
102
+ }): void {
103
+ if (!config.enabled) return;
104
+
105
+ // Clear only overlays that overlap with the insertion range
106
+ // These overlays may now span corrupted content (e.g., "TODO" -> "TOxDO")
107
+ // The affected lines will be re-sent via lines_changed with correct content
108
+ editor.clearOverlaysInRange(data.buffer_id, data.affected_start, data.affected_end);
109
+ };
110
+
111
+ globalThis.onAfterDelete = function(data: {
112
+ buffer_id: number;
113
+ start: number;
114
+ end: number;
115
+ deleted_text: string;
116
+ affected_start: number;
117
+ deleted_len: number;
118
+ }): void {
119
+ if (!config.enabled) return;
120
+
121
+ // Clear overlays that overlapped with the deleted range
122
+ // Overlays that were entirely within the deleted range are already gone
123
+ // (their markers were deleted), but overlays that spanned the deletion
124
+ // boundary may now be incorrect
125
+ // Use a slightly expanded range to catch boundary cases
126
+ const clearStart = data.affected_start > 0 ? data.affected_start - 1 : 0;
127
+ const clearEnd = data.affected_start + 1;
128
+ editor.clearOverlaysInRange(data.buffer_id, clearStart, clearEnd);
129
+ };
130
+
131
+ // Handle buffer close events
132
+ globalThis.onBufferClosed = function(data: { buffer_id: number }): void {
133
+ // No cleanup needed - overlays are automatically cleaned up with the buffer
134
+ };
135
+
136
+ // Register hooks
137
+ editor.on("lines_changed", "onLinesChanged");
138
+ editor.on("after_insert", "onAfterInsert");
139
+ editor.on("after_delete", "onAfterDelete");
140
+ editor.on("buffer_closed", "onBufferClosed");
141
+
142
+ // Plugin commands
143
+ globalThis.todoHighlighterEnable = function(): void {
144
+ config.enabled = true;
145
+ // Refresh lines so next render processes all visible lines
146
+ const bufferId = editor.getActiveBufferId();
147
+ editor.refreshLines(bufferId);
148
+ editor.setStatus(editor.t("status.enabled"));
149
+ };
150
+
151
+ globalThis.todoHighlighterDisable = function(): void {
152
+ config.enabled = false;
153
+ const bufferId = editor.getActiveBufferId();
154
+ clearHighlights(bufferId);
155
+ editor.setStatus(editor.t("status.disabled"));
156
+ };
157
+
158
+ globalThis.todoHighlighterToggle = function(): void {
159
+ config.enabled = !config.enabled;
160
+ const bufferId = editor.getActiveBufferId();
161
+ if (config.enabled) {
162
+ // Refresh lines so next render processes all visible lines
163
+ editor.refreshLines(bufferId);
164
+ } else {
165
+ clearHighlights(bufferId);
166
+ }
167
+ editor.setStatus(config.enabled ? editor.t("status.enabled") : editor.t("status.disabled"));
168
+ };
169
+
170
+ globalThis.todoHighlighterShowKeywords = function(): void {
171
+ const keywords = config.keywords.map(k => k.word).join(", ");
172
+ editor.setStatus(editor.t("status.keywords", { keywords }));
173
+ };
174
+
175
+ // Register commands
176
+ editor.registerCommand(
177
+ "%cmd.enable",
178
+ "%cmd.enable_desc",
179
+ "todoHighlighterEnable",
180
+ "normal"
181
+ );
182
+
183
+ editor.registerCommand(
184
+ "%cmd.disable",
185
+ "%cmd.disable_desc",
186
+ "todoHighlighterDisable",
187
+ "normal"
188
+ );
189
+
190
+ editor.registerCommand(
191
+ "%cmd.toggle",
192
+ "%cmd.toggle_desc",
193
+ "todoHighlighterToggle",
194
+ "normal"
195
+ );
196
+
197
+ editor.registerCommand(
198
+ "%cmd.show_keywords",
199
+ "%cmd.show_keywords_desc",
200
+ "todoHighlighterShowKeywords",
201
+ "normal"
202
+ );
203
+
204
+ // Initialization
205
+ editor.setStatus(editor.t("status.loaded"));
206
+ editor.debug("TODO Highlighter initialized with keywords: " + config.keywords.map(k => k.word).join(", "));
@@ -0,0 +1,167 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+
5
+ /**
6
+ * TypeScript/JavaScript LSP Helper Plugin
7
+ *
8
+ * Provides user-friendly error handling for TypeScript/JavaScript LSP server issues.
9
+ * When typescript-language-server fails to start, this plugin shows an actionable
10
+ * popup with installation instructions.
11
+ *
12
+ * Features:
13
+ * - Detects TypeScript LSP server errors (typescript-language-server, tsserver)
14
+ * - Shows popup with install commands (npm, yarn, pnpm)
15
+ * - Allows copying install commands to clipboard
16
+ * - Provides option to disable TypeScript LSP
17
+ */
18
+
19
+ interface LspServerErrorData {
20
+ language: string;
21
+ server_command: string;
22
+ error_type: string;
23
+ message: string;
24
+ }
25
+
26
+ interface LspStatusClickedData {
27
+ language: string;
28
+ has_error: boolean;
29
+ }
30
+
31
+ interface ActionPopupResultData {
32
+ popup_id: string;
33
+ action_id: string;
34
+ }
35
+
36
+ // Install commands for TypeScript LSP server
37
+ // Both typescript-language-server AND typescript packages are required
38
+ // See: https://github.com/typescript-language-server/typescript-language-server
39
+ const INSTALL_COMMANDS = {
40
+ npm: "npm install -g typescript-language-server typescript",
41
+ yarn: "yarn global add typescript-language-server typescript",
42
+ pnpm: "pnpm add -g typescript-language-server typescript",
43
+ };
44
+
45
+ // Languages handled by this plugin
46
+ const HANDLED_LANGUAGES = ["typescript", "javascript", "typescriptreact", "javascriptreact"];
47
+
48
+ // Track error state for TypeScript LSP
49
+ let tsLspError: { serverCommand: string; message: string; language: string } | null = null;
50
+
51
+ /**
52
+ * Handle LSP server errors for TypeScript/JavaScript
53
+ */
54
+ globalThis.on_typescript_lsp_server_error = function (
55
+ data: LspServerErrorData
56
+ ): void {
57
+ // Only handle TypeScript/JavaScript language errors
58
+ if (!HANDLED_LANGUAGES.includes(data.language)) {
59
+ return;
60
+ }
61
+
62
+ editor.debug(
63
+ `typescript-lsp: Server error - ${data.error_type}: ${data.message}`
64
+ );
65
+
66
+ // Store error state for later reference
67
+ tsLspError = {
68
+ serverCommand: data.server_command,
69
+ message: data.message,
70
+ language: data.language,
71
+ };
72
+
73
+ // Show a status message for immediate feedback
74
+ if (data.error_type === "not_found") {
75
+ editor.setStatus(
76
+ `TypeScript LSP server '${data.server_command}' not found. Click status bar for help.`
77
+ );
78
+ } else {
79
+ editor.setStatus(`TypeScript LSP error: ${data.message}`);
80
+ }
81
+ };
82
+
83
+ // Register hook for LSP server errors
84
+ editor.on("lsp_server_error", "on_typescript_lsp_server_error");
85
+
86
+ /**
87
+ * Handle status bar click when there's a TypeScript LSP error
88
+ */
89
+ globalThis.on_typescript_lsp_status_clicked = function (
90
+ data: LspStatusClickedData
91
+ ): void {
92
+ // Only handle TypeScript/JavaScript language clicks when there's an error
93
+ if (!HANDLED_LANGUAGES.includes(data.language) || !tsLspError) {
94
+ return;
95
+ }
96
+
97
+ editor.debug("typescript-lsp: Status clicked, showing help popup");
98
+
99
+ // Show action popup with install options
100
+ editor.showActionPopup({
101
+ id: "typescript-lsp-help",
102
+ title: "TypeScript Language Server Not Found",
103
+ message: `"${tsLspError.serverCommand}" provides code completion, diagnostics, and navigation for TypeScript/JavaScript files. Copy a command below to install it, or search online for your platform.`,
104
+ actions: [
105
+ { id: "copy_npm", label: `Copy: ${INSTALL_COMMANDS.npm}` },
106
+ { id: "copy_yarn", label: `Copy: ${INSTALL_COMMANDS.yarn}` },
107
+ { id: "copy_pnpm", label: `Copy: ${INSTALL_COMMANDS.pnpm}` },
108
+ { id: "disable", label: "Disable TypeScript LSP" },
109
+ { id: "dismiss", label: "Dismiss (ESC)" },
110
+ ],
111
+ });
112
+ };
113
+
114
+ // Register hook for status bar clicks
115
+ editor.on("lsp_status_clicked", "on_typescript_lsp_status_clicked");
116
+
117
+ /**
118
+ * Handle action popup results for TypeScript LSP help
119
+ */
120
+ globalThis.on_typescript_lsp_action_result = function (
121
+ data: ActionPopupResultData
122
+ ): void {
123
+ // Only handle our popup
124
+ if (data.popup_id !== "typescript-lsp-help") {
125
+ return;
126
+ }
127
+
128
+ editor.debug(`typescript-lsp: Action selected - ${data.action_id}`);
129
+
130
+ switch (data.action_id) {
131
+ case "copy_npm":
132
+ editor.setClipboard(INSTALL_COMMANDS.npm);
133
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.npm);
134
+ break;
135
+
136
+ case "copy_yarn":
137
+ editor.setClipboard(INSTALL_COMMANDS.yarn);
138
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.yarn);
139
+ break;
140
+
141
+ case "copy_pnpm":
142
+ editor.setClipboard(INSTALL_COMMANDS.pnpm);
143
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.pnpm);
144
+ break;
145
+
146
+ case "disable":
147
+ // Disable for all TypeScript/JavaScript variants
148
+ editor.disableLspForLanguage("typescript");
149
+ editor.disableLspForLanguage("javascript");
150
+ editor.setStatus("TypeScript/JavaScript LSP disabled");
151
+ tsLspError = null;
152
+ break;
153
+
154
+ case "dismiss":
155
+ case "dismissed":
156
+ // Just close the popup without action
157
+ break;
158
+
159
+ default:
160
+ editor.debug(`typescript-lsp: Unknown action: ${data.action_id}`);
161
+ }
162
+ };
163
+
164
+ // Register hook for action popup results
165
+ editor.on("action_popup_result", "on_typescript_lsp_action_result");
166
+
167
+ editor.debug("typescript-lsp: Plugin loaded");