@fresh-editor/fresh-editor 0.1.4

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 (38) hide show
  1. package/.gitignore +2 -0
  2. package/LICENSE +117 -0
  3. package/README.md +54 -0
  4. package/binary-install.js +212 -0
  5. package/binary.js +126 -0
  6. package/install.js +4 -0
  7. package/npm-shrinkwrap.json +900 -0
  8. package/package.json +100 -0
  9. package/plugins/README.md +121 -0
  10. package/plugins/clangd_support.md +20 -0
  11. package/plugins/clangd_support.ts +323 -0
  12. package/plugins/color_highlighter.ts +302 -0
  13. package/plugins/diagnostics_panel.ts +308 -0
  14. package/plugins/examples/README.md +245 -0
  15. package/plugins/examples/async_demo.ts +165 -0
  16. package/plugins/examples/bookmarks.ts +329 -0
  17. package/plugins/examples/buffer_query_demo.ts +110 -0
  18. package/plugins/examples/git_grep.ts +262 -0
  19. package/plugins/examples/hello_world.ts +93 -0
  20. package/plugins/examples/virtual_buffer_demo.ts +116 -0
  21. package/plugins/find_references.ts +357 -0
  22. package/plugins/git_find_file.ts +298 -0
  23. package/plugins/git_grep.ts +188 -0
  24. package/plugins/git_log.ts +1283 -0
  25. package/plugins/lib/fresh.d.ts +849 -0
  26. package/plugins/lib/index.ts +24 -0
  27. package/plugins/lib/navigation-controller.ts +214 -0
  28. package/plugins/lib/panel-manager.ts +218 -0
  29. package/plugins/lib/types.ts +72 -0
  30. package/plugins/lib/virtual-buffer-factory.ts +158 -0
  31. package/plugins/manual_help.ts +243 -0
  32. package/plugins/markdown_compose.ts +1207 -0
  33. package/plugins/merge_conflict.ts +1811 -0
  34. package/plugins/path_complete.ts +163 -0
  35. package/plugins/search_replace.ts +481 -0
  36. package/plugins/todo_highlighter.ts +204 -0
  37. package/plugins/welcome.ts +74 -0
  38. package/run-fresh.js +4 -0
@@ -0,0 +1,204 @@
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
+
5
+ interface HighlightConfig {
6
+ enabled: boolean;
7
+ keywords: Array<{
8
+ word: string;
9
+ color: [number, number, number];
10
+ }>;
11
+ }
12
+
13
+ // Plugin configuration
14
+ const config: HighlightConfig = {
15
+ enabled: false, // Start disabled, use Enable or Toggle to activate
16
+ keywords: [
17
+ { word: "TODO", color: [255, 200, 50] }, // Yellow
18
+ { word: "FIXME", color: [255, 100, 100] }, // Red
19
+ { word: "XXX", color: [255, 150, 50] }, // Orange
20
+ { word: "HACK", color: [200, 100, 255] }, // Purple
21
+ { word: "NOTE", color: [100, 200, 255] }, // Blue
22
+ ],
23
+ };
24
+
25
+ // Namespace for all TODO highlighter overlays
26
+ const NAMESPACE = "todo";
27
+
28
+ // Process a single line for keyword highlighting
29
+ function highlightLine(
30
+ bufferId: number,
31
+ byteStart: number,
32
+ content: string
33
+ ): void {
34
+ // Search for keywords
35
+ for (const keyword of config.keywords) {
36
+ let searchStart = 0;
37
+ while (true) {
38
+ const pos = content.indexOf(keyword.word, searchStart);
39
+ if (pos === -1) break;
40
+
41
+ // Check if it's a whole word (preceded by non-word char or start)
42
+ const isWordStart = pos === 0 || !/\w/.test(content[pos - 1]);
43
+ const isWordEnd = pos + keyword.word.length >= content.length ||
44
+ !/\w/.test(content[pos + keyword.word.length]);
45
+
46
+ if (isWordStart && isWordEnd) {
47
+ const absoluteStart = byteStart + pos;
48
+ const absoluteEnd = absoluteStart + keyword.word.length;
49
+
50
+ // Add overlay with namespace for efficient batch removal
51
+ editor.addOverlay(
52
+ bufferId,
53
+ NAMESPACE,
54
+ absoluteStart,
55
+ absoluteEnd,
56
+ keyword.color[0],
57
+ keyword.color[1],
58
+ keyword.color[2],
59
+ false // background color, not underline
60
+ );
61
+ }
62
+
63
+ searchStart = pos + 1;
64
+ }
65
+ }
66
+ }
67
+
68
+ // Clear highlights for a buffer using namespace
69
+ function clearHighlights(bufferId: number): void {
70
+ editor.clearNamespace(bufferId, NAMESPACE);
71
+ }
72
+
73
+ // Handle lines_changed events (batched for efficiency)
74
+ // This is called for lines that need (re)processing
75
+ globalThis.onLinesChanged = function(data: {
76
+ buffer_id: number;
77
+ lines: Array<{
78
+ line_number: number;
79
+ byte_start: number;
80
+ byte_end: number;
81
+ content: string;
82
+ }>;
83
+ }): void {
84
+ if (!config.enabled) return;
85
+
86
+ // Process all changed lines and create overlays for them
87
+ for (const line of data.lines) {
88
+ highlightLine(data.buffer_id, line.byte_start, line.content);
89
+ }
90
+ };
91
+
92
+ // Handle buffer content changes - clear only affected overlays
93
+ // The editor will automatically re-send the affected lines via lines_changed
94
+ globalThis.onAfterInsert = function(data: {
95
+ buffer_id: number;
96
+ position: number;
97
+ text: string;
98
+ affected_start: number;
99
+ affected_end: number;
100
+ }): void {
101
+ if (!config.enabled) return;
102
+
103
+ // Clear only overlays that overlap with the insertion range
104
+ // These overlays may now span corrupted content (e.g., "TODO" -> "TOxDO")
105
+ // The affected lines will be re-sent via lines_changed with correct content
106
+ editor.clearOverlaysInRange(data.buffer_id, data.affected_start, data.affected_end);
107
+ };
108
+
109
+ globalThis.onAfterDelete = function(data: {
110
+ buffer_id: number;
111
+ start: number;
112
+ end: number;
113
+ deleted_text: string;
114
+ affected_start: number;
115
+ deleted_len: number;
116
+ }): void {
117
+ if (!config.enabled) return;
118
+
119
+ // Clear overlays that overlapped with the deleted range
120
+ // Overlays that were entirely within the deleted range are already gone
121
+ // (their markers were deleted), but overlays that spanned the deletion
122
+ // boundary may now be incorrect
123
+ // Use a slightly expanded range to catch boundary cases
124
+ const clearStart = data.affected_start > 0 ? data.affected_start - 1 : 0;
125
+ const clearEnd = data.affected_start + 1;
126
+ editor.clearOverlaysInRange(data.buffer_id, clearStart, clearEnd);
127
+ };
128
+
129
+ // Handle buffer close events
130
+ globalThis.onBufferClosed = function(data: { buffer_id: number }): void {
131
+ // No cleanup needed - overlays are automatically cleaned up with the buffer
132
+ };
133
+
134
+ // Register hooks
135
+ editor.on("lines_changed", "onLinesChanged");
136
+ editor.on("after-insert", "onAfterInsert");
137
+ editor.on("after-delete", "onAfterDelete");
138
+ editor.on("buffer_closed", "onBufferClosed");
139
+
140
+ // Plugin commands
141
+ globalThis.todoHighlighterEnable = function(): void {
142
+ config.enabled = true;
143
+ // Refresh lines so next render processes all visible lines
144
+ const bufferId = editor.getActiveBufferId();
145
+ editor.refreshLines(bufferId);
146
+ editor.setStatus("TODO Highlighter: Enabled");
147
+ };
148
+
149
+ globalThis.todoHighlighterDisable = function(): void {
150
+ config.enabled = false;
151
+ const bufferId = editor.getActiveBufferId();
152
+ clearHighlights(bufferId);
153
+ editor.setStatus("TODO Highlighter: Disabled");
154
+ };
155
+
156
+ globalThis.todoHighlighterToggle = function(): void {
157
+ config.enabled = !config.enabled;
158
+ const bufferId = editor.getActiveBufferId();
159
+ if (config.enabled) {
160
+ // Refresh lines so next render processes all visible lines
161
+ editor.refreshLines(bufferId);
162
+ } else {
163
+ clearHighlights(bufferId);
164
+ }
165
+ editor.setStatus(`TODO Highlighter: ${config.enabled ? "Enabled" : "Disabled"}`);
166
+ };
167
+
168
+ globalThis.todoHighlighterShowKeywords = function(): void {
169
+ const keywords = config.keywords.map(k => k.word).join(", ");
170
+ editor.setStatus(`TODO Keywords: ${keywords}`);
171
+ };
172
+
173
+ // Register commands
174
+ editor.registerCommand(
175
+ "TODO Highlighter: Enable",
176
+ "Enable TODO keyword highlighting",
177
+ "todoHighlighterEnable",
178
+ "normal"
179
+ );
180
+
181
+ editor.registerCommand(
182
+ "TODO Highlighter: Disable",
183
+ "Disable TODO keyword highlighting",
184
+ "todoHighlighterDisable",
185
+ "normal"
186
+ );
187
+
188
+ editor.registerCommand(
189
+ "TODO Highlighter: Toggle",
190
+ "Toggle TODO keyword highlighting",
191
+ "todoHighlighterToggle",
192
+ "normal"
193
+ );
194
+
195
+ editor.registerCommand(
196
+ "TODO Highlighter: Show Keywords",
197
+ "Show currently tracked keywords",
198
+ "todoHighlighterShowKeywords",
199
+ "normal"
200
+ );
201
+
202
+ // Initialization
203
+ editor.setStatus("TODO Highlighter plugin loaded (TypeScript)");
204
+ editor.debug("TODO Highlighter initialized with keywords: " + config.keywords.map(k => k.word).join(", "));
@@ -0,0 +1,74 @@
1
+ /// <reference path="../types/fresh.d.ts" />
2
+
3
+ /**
4
+ * Welcome Plugin
5
+ * Shows a welcome message and registers demo commands
6
+ */
7
+
8
+ // Show welcome message in status bar
9
+ editor.setStatus("Plugins are working! Welcome Plugin loaded successfully!");
10
+
11
+ // Register commands that use built-in actions
12
+ editor.registerCommand(
13
+ "Plugin Demo: Open Help",
14
+ "Open the editor help page (uses built-in action)",
15
+ "show_help",
16
+ "normal"
17
+ );
18
+
19
+ editor.registerCommand(
20
+ "Plugin Demo: Save File",
21
+ "Save the current file (uses built-in action)",
22
+ "save",
23
+ "normal"
24
+ );
25
+
26
+ // Register commands with custom TypeScript callbacks
27
+ globalThis.plugin_say_hello = function(): void {
28
+ editor.insertAtCursor("Hello from TypeScript! The plugin system is working!\n");
29
+ editor.setStatus("Inserted greeting at cursor position");
30
+ editor.debug("Plugin callback executed: say_hello");
31
+ };
32
+
33
+ editor.registerCommand(
34
+ "Plugin Demo: Say Hello",
35
+ "Insert a friendly greeting into the buffer",
36
+ "plugin_say_hello",
37
+ "normal"
38
+ );
39
+
40
+ globalThis.plugin_insert_time = function(): void {
41
+ const time = new Date().toLocaleTimeString();
42
+ editor.insertAtCursor(`Current time: ${time}\n`);
43
+ editor.setStatus("Inserted time at cursor position");
44
+ editor.debug(`Plugin callback executed: insert_time at ${time}`);
45
+ };
46
+
47
+ editor.registerCommand(
48
+ "Plugin Demo: Insert Time",
49
+ "Insert the current time at cursor position",
50
+ "plugin_insert_time",
51
+ "normal"
52
+ );
53
+
54
+ globalThis.plugin_insert_comment = function(): void {
55
+ editor.insertAtCursor("// This comment was inserted by a TypeScript plugin!\n");
56
+ editor.setStatus("Comment inserted by plugin");
57
+ editor.debug("Plugin callback executed: insert_comment");
58
+ };
59
+
60
+ editor.registerCommand(
61
+ "Plugin Demo: Insert Comment",
62
+ "Insert a sample comment at cursor position",
63
+ "plugin_insert_comment",
64
+ "normal"
65
+ );
66
+
67
+ // Debug output
68
+ editor.debug("Welcome plugin initialized successfully!");
69
+ editor.debug("Registered 5 commands - try Ctrl+P to see them!");
70
+ editor.debug(" - 'Plugin Demo: Open Help' - toggles help screen (built-in action)");
71
+ editor.debug(" - 'Plugin Demo: Save File' - saves current file (built-in action)");
72
+ editor.debug(" - 'Plugin Demo: Say Hello' - inserts greeting (TypeScript callback)");
73
+ editor.debug(" - 'Plugin Demo: Insert Time' - inserts current time (TypeScript callback)");
74
+ editor.debug(" - 'Plugin Demo: Insert Comment' - inserts sample comment (TypeScript callback)");
package/run-fresh.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { run } = require("./binary");
4
+ run("fresh");