@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.
- package/bin/CHANGELOG.md +1017 -0
- package/bin/LICENSE +117 -0
- package/bin/README.md +248 -0
- package/bin/fresh.exe +0 -0
- package/bin/plugins/README.md +71 -0
- package/bin/plugins/audit_mode.i18n.json +821 -0
- package/bin/plugins/audit_mode.ts +1810 -0
- package/bin/plugins/buffer_modified.i18n.json +67 -0
- package/bin/plugins/buffer_modified.ts +281 -0
- package/bin/plugins/calculator.i18n.json +93 -0
- package/bin/plugins/calculator.ts +770 -0
- package/bin/plugins/clangd-lsp.ts +168 -0
- package/bin/plugins/clangd_support.i18n.json +223 -0
- package/bin/plugins/clangd_support.md +20 -0
- package/bin/plugins/clangd_support.ts +325 -0
- package/bin/plugins/color_highlighter.i18n.json +145 -0
- package/bin/plugins/color_highlighter.ts +304 -0
- package/bin/plugins/config-schema.json +768 -0
- package/bin/plugins/csharp-lsp.ts +147 -0
- package/bin/plugins/csharp_support.i18n.json +80 -0
- package/bin/plugins/csharp_support.ts +170 -0
- package/bin/plugins/css-lsp.ts +143 -0
- package/bin/plugins/diagnostics_panel.i18n.json +236 -0
- package/bin/plugins/diagnostics_panel.ts +642 -0
- package/bin/plugins/examples/README.md +85 -0
- package/bin/plugins/examples/async_demo.ts +165 -0
- package/bin/plugins/examples/bookmarks.ts +329 -0
- package/bin/plugins/examples/buffer_query_demo.ts +110 -0
- package/bin/plugins/examples/git_grep.ts +262 -0
- package/bin/plugins/examples/hello_world.ts +93 -0
- package/bin/plugins/examples/virtual_buffer_demo.ts +116 -0
- package/bin/plugins/find_references.i18n.json +275 -0
- package/bin/plugins/find_references.ts +359 -0
- package/bin/plugins/git_blame.i18n.json +496 -0
- package/bin/plugins/git_blame.ts +707 -0
- package/bin/plugins/git_find_file.i18n.json +314 -0
- package/bin/plugins/git_find_file.ts +300 -0
- package/bin/plugins/git_grep.i18n.json +171 -0
- package/bin/plugins/git_grep.ts +191 -0
- package/bin/plugins/git_gutter.i18n.json +93 -0
- package/bin/plugins/git_gutter.ts +477 -0
- package/bin/plugins/git_log.i18n.json +481 -0
- package/bin/plugins/git_log.ts +1285 -0
- package/bin/plugins/go-lsp.ts +143 -0
- package/bin/plugins/html-lsp.ts +145 -0
- package/bin/plugins/json-lsp.ts +145 -0
- package/bin/plugins/lib/fresh.d.ts +1321 -0
- package/bin/plugins/lib/index.ts +24 -0
- package/bin/plugins/lib/navigation-controller.ts +214 -0
- package/bin/plugins/lib/panel-manager.ts +220 -0
- package/bin/plugins/lib/types.ts +72 -0
- package/bin/plugins/lib/virtual-buffer-factory.ts +130 -0
- package/bin/plugins/live_grep.i18n.json +171 -0
- package/bin/plugins/live_grep.ts +422 -0
- package/bin/plugins/markdown_compose.i18n.json +223 -0
- package/bin/plugins/markdown_compose.ts +630 -0
- package/bin/plugins/merge_conflict.i18n.json +821 -0
- package/bin/plugins/merge_conflict.ts +1810 -0
- package/bin/plugins/path_complete.i18n.json +80 -0
- package/bin/plugins/path_complete.ts +165 -0
- package/bin/plugins/python-lsp.ts +162 -0
- package/bin/plugins/rust-lsp.ts +166 -0
- package/bin/plugins/search_replace.i18n.json +405 -0
- package/bin/plugins/search_replace.ts +484 -0
- package/bin/plugins/test_i18n.i18n.json +67 -0
- package/bin/plugins/test_i18n.ts +18 -0
- package/bin/plugins/theme_editor.i18n.json +3746 -0
- package/bin/plugins/theme_editor.ts +2063 -0
- package/bin/plugins/todo_highlighter.i18n.json +184 -0
- package/bin/plugins/todo_highlighter.ts +206 -0
- package/bin/plugins/typescript-lsp.ts +167 -0
- package/bin/plugins/vi_mode.i18n.json +1549 -0
- package/bin/plugins/vi_mode.ts +2747 -0
- package/bin/plugins/welcome.i18n.json +236 -0
- package/bin/plugins/welcome.ts +76 -0
- package/bin/themes/dark.json +102 -0
- package/bin/themes/dracula.json +62 -0
- package/bin/themes/high-contrast.json +102 -0
- package/bin/themes/light.json +102 -0
- package/bin/themes/nord.json +62 -0
- package/bin/themes/nostalgia.json +102 -0
- package/bin/themes/solarized-dark.json +62 -0
- package/binary-install.js +1 -1
- package/dist/bin/fresh.js +9 -0
- package/dist/binary-install.js +149 -0
- package/dist/binary.js +30 -0
- package/dist/fresh-6yhknp07.exe +0 -0
- package/dist/install.js +158 -0
- package/dist/run-fresh.js +43 -0
- 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");
|