@fresh-editor/fresh-editor 0.1.6 → 0.1.7

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.
@@ -23,7 +23,7 @@
23
23
  "hasInstallScript": true,
24
24
  "license": "GPL-2.0",
25
25
  "name": "@fresh-editor/fresh-editor",
26
- "version": "0.1.6"
26
+ "version": "0.1.7"
27
27
  },
28
28
  "node_modules/@isaacs/balanced-match": {
29
29
  "engines": {
@@ -896,5 +896,5 @@
896
896
  }
897
897
  },
898
898
  "requires": true,
899
- "version": "0.1.6"
899
+ "version": "0.1.7"
900
900
  }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "artifactDownloadUrl": "https://github.com/sinelaw/fresh/releases/download/v0.1.6",
2
+ "artifactDownloadUrl": "https://github.com/sinelaw/fresh/releases/download/v0.1.7",
3
3
  "author": "Noam Lewis",
4
4
  "bin": {
5
5
  "fresh": "run-fresh.js"
@@ -92,7 +92,7 @@
92
92
  "zipExt": ".tar.xz"
93
93
  }
94
94
  },
95
- "version": "0.1.6",
95
+ "version": "0.1.7",
96
96
  "volta": {
97
97
  "node": "18.14.1",
98
98
  "npm": "9.5.0"
package/plugins/README.md CHANGED
@@ -1,121 +1,71 @@
1
1
  # Plugins
2
2
 
3
- This directory contains production-ready plugins for the editor. Plugins are automatically loaded when the editor starts.
3
+ This directory contains production-ready plugins for the editor. Plugins are written in **TypeScript** and run in a sandboxed Deno environment. They are automatically loaded when the editor starts.
4
4
 
5
5
  ## Available Plugins
6
6
 
7
- ### TODO Highlighter (`todo_highlighter.lua`)
8
-
9
- **A complete, useful plugin demonstrating Phase 2 API capabilities.**
10
-
11
- Highlights TODO/FIXME/HACK/NOTE/XXX/BUG keywords in comments with color-coded overlays.
12
-
13
- **Features:**
14
- - Multi-language comment support (C/C++, Python, Lua, JavaScript, HTML, etc.)
15
- - Color-coded highlighting:
16
- - 🟠 **TODO** - Orange (tasks to do)
17
- - 🔴 **FIXME** - Red (things to fix)
18
- - 🟡 **HACK** - Yellow (temporary workarounds)
19
- - 🟢 **NOTE** - Green (important notes)
20
- - 🟣 **XXX** - Magenta (items needing review)
21
- - 🔺 **BUG** - Dark Red (known bugs)
22
- - Smart comment detection (only highlights keywords in comments, not in regular text)
23
-
24
- **Commands:**
25
- - `TODO Highlighter: Toggle` - Enable/disable highlighting
26
- - `TODO Highlighter: Enable` - Turn on highlighting
27
- - `TODO Highlighter: Disable` - Turn off and clear highlights
28
- - `TODO Highlighter: Refresh` - Re-scan current buffer
29
- - `TODO Highlighter: Show Keywords` - Display tracked keywords
30
-
31
- **Usage:**
32
- 1. Open any file with TODO comments
33
- 2. Press `Ctrl+P` to open command palette
34
- 3. Type "TODO" and select `TODO Highlighter: Toggle`
35
- 4. Keywords in comments will be highlighted!
36
-
37
- **APIs Used:**
38
- - Buffer Query API: `get_active_buffer_id()`, `get_buffer_content()`
39
- - Overlay API: `add_overlay()`, `remove_overlay()`
40
- - Command Registration: `register_command()`
7
+ ### Core Plugins
41
8
 
42
- ---
43
-
44
- ### Git Grep (`git-grep.lua`)
45
-
46
- **Full-featured git grep with hook-based prompt API (Phase 2 - Jan 2025)**
47
-
48
- Interactive search through all git-tracked files with real-time results.
9
+ | Plugin | Description |
10
+ |--------|-------------|
11
+ | `welcome.ts` | Displays welcome message on startup |
12
+ | `manual_help.ts` | Manual page and keyboard shortcuts display |
13
+ | `diagnostics_panel.ts` | LSP diagnostics panel with navigation |
14
+ | `search_replace.ts` | Search and replace functionality |
15
+ | `path_complete.ts` | Path completion in prompts |
49
16
 
50
- **Features:**
51
- - Search as you type with async git grep
52
- - Shows file:line:column context for each match
53
- - Opens files at exact match location
54
- - Graceful handling of empty results and errors
55
- - ~150 lines of Lua demonstrating prompt API
17
+ ### Git Integration
56
18
 
57
- **Usage:**
58
- ```lua
59
- start_git_grep() -- From Lua or keybinding
60
- ```
61
- Or use command palette: "Git Grep"
62
-
63
- **APIs Used:**
64
- - Hook-based Prompt API: `start_prompt()`, `set_prompt_suggestions()`
65
- - Prompt Hooks: `prompt-changed`, `prompt-confirmed`, `prompt-cancelled`
66
- - Async Process: `editor.spawn()`
67
- - File Navigation: `editor.open_file({path, line, column})`
68
-
69
- ---
19
+ | Plugin | Description |
20
+ |--------|-------------|
21
+ | `git_grep.ts` | Interactive search through git-tracked files |
22
+ | `git_find_file.ts` | Fuzzy file finder for git repositories |
23
+ | `git_blame.ts` | Git blame view with commit navigation |
24
+ | `git_log.ts` | Git log viewer with history browsing |
70
25
 
71
- ### Git Find File (`git-find-file.lua`)
26
+ ### Code Enhancement
72
27
 
73
- **Fast fuzzy file finder for git repos (Phase 2 - Jan 2025)**
28
+ | Plugin | Description |
29
+ |--------|-------------|
30
+ | `todo_highlighter.ts` | Highlights TODO/FIXME/HACK keywords in comments |
31
+ | `color_highlighter.ts` | Highlights color codes with their actual colors |
32
+ | `find_references.ts` | Find references across the codebase |
33
+ | `clangd_support.ts` | Clangd-specific LSP features (switch header/source) |
74
34
 
75
- Find and open git-tracked files with fuzzy matching, similar to Ctrl+P in VSCode.
35
+ ### Editing Modes
76
36
 
77
- **Features:**
78
- - Fuzzy file name filtering (all chars match in order)
79
- - Caches git ls-files for instant filtering
80
- - Shows up to 100 matches in real-time
81
- - Opens selected file or manual path
82
- - ~150 lines of pure Lua implementation
37
+ | Plugin | Description |
38
+ |--------|-------------|
39
+ | `markdown_compose.ts` | Semi-WYSIWYG markdown editing with soft breaks |
40
+ | `merge_conflict.ts` | 3-way merge conflict resolution |
83
41
 
84
- **Usage:**
85
- ```lua
86
- start_git_find_file() -- From Lua or keybinding
87
- ```
88
- Or use command palette: "Git Find File"
42
+ ### Development/Testing
89
43
 
90
- **APIs Used:**
91
- - Same hook-based prompt API as git grep
92
- - Demonstrates reusability of prompt system
93
- - Pure Lua fuzzy matching algorithm
94
-
95
- ---
96
-
97
- ### Welcome (`welcome.lua`)
98
-
99
- Simple welcome message plugin that demonstrates basic plugin loading and status messages.
100
-
101
- **Commands:**
102
- - Various demo commands showing basic plugin capabilities
44
+ | Plugin | Description |
45
+ |--------|-------------|
46
+ | `test_view_marker.ts` | Testing utilities for view markers |
103
47
 
104
48
  ---
105
49
 
106
50
  ## Example Plugins
107
51
 
108
- See `examples/` directory for educational examples demonstrating specific API features:
109
- - `hello.lua` - Minimal plugin example
110
- - `highlight_demo.lua` - Overlay API demonstrations
111
- - `buffer_query_demo.lua` - Buffer state querying (Phase 2)
112
- - `async_demo.lua` - Async process spawning (Phase 2)
52
+ The `examples/` directory contains educational examples demonstrating specific API features:
53
+
54
+ | Example | Description |
55
+ |---------|-------------|
56
+ | `hello_world.ts` | Minimal plugin demonstrating command registration |
57
+ | `async_demo.ts` | Async process spawning |
58
+ | `buffer_query_demo.ts` | Buffer state querying |
59
+ | `virtual_buffer_demo.ts` | Creating virtual buffers with text properties |
60
+ | `bookmarks.ts` | Bookmark management example |
61
+ | `git_grep.ts` | Git grep implementation example |
113
62
 
114
63
  ---
115
64
 
116
65
  ## Plugin Development
117
66
 
118
67
  For plugin development guides, see:
119
- - **Quick Start:** `../PLUGINS_QUICKSTART.md`
120
- - **API Reference:** `examples/README.md`
121
- - **Implementation:** `../docs/PLUGIN_SYSTEM_IMPLEMENTATION.md`
68
+ - **Getting Started:** [`docs/PLUGIN_DEVELOPMENT.md`](../docs/PLUGIN_DEVELOPMENT.md)
69
+ - **API Reference:** [`docs/plugin-api.md`](../docs/plugin-api.md)
70
+ - **Examples:** [`examples/README.md`](examples/README.md)
71
+ - **Clangd Plugin:** [`clangd_support.md`](clangd_support.md)
@@ -1,245 +1,85 @@
1
1
  # Example Plugins
2
2
 
3
- This directory contains example plugins demonstrating the editor's plugin system.
3
+ This directory contains example plugins demonstrating the editor's plugin system. These are educational examples showing specific API features.
4
+
5
+ For the complete API reference, see **[docs/plugin-api.md](../../docs/plugin-api.md)**.
4
6
 
5
7
  ## Available Examples
6
8
 
7
- ### hello.lua
9
+ ### hello_world.ts
10
+
8
11
  A simple "Hello World" plugin that demonstrates:
9
12
  - Registering a custom command
10
13
  - Setting status messages
11
14
  - Basic plugin structure
12
15
 
13
- ### highlight_demo.lua
14
- Demonstrates visual overlays:
15
- - Multiple command registration
16
- - Adding colored overlays to buffers
17
- - Using the overlay API
18
-
19
- ### git_grep_demo.lua
20
- Simple demo of git integration and file navigation:
21
- - Spawning async git processes
22
- - Parsing git grep output
23
- - Opening files at specific line:column positions
24
- - Basic prototype (see full plugins in parent directory)
16
+ ### async_demo.ts
25
17
 
26
- ### async_demo.lua
27
18
  Demonstrates async process spawning:
28
- - Running external commands
19
+ - Running external commands with `spawnProcess`
29
20
  - Processing stdout/stderr
30
21
  - Handling exit codes
31
22
 
32
- ### buffer_query_demo.lua
23
+ ### buffer_query_demo.ts
24
+
33
25
  Demonstrates buffer queries:
34
- - Getting buffer metadata
26
+ - Getting buffer metadata with `getBufferInfo`
35
27
  - Listing all open buffers
36
28
  - Querying cursor and viewport information
37
29
 
38
- ## Plugin API
39
-
40
- ### Available Functions
41
-
42
- #### editor.register_command(command_table)
43
- Register a new command in the command palette.
44
-
45
- ```lua
46
- editor.register_command({
47
- name = "My Command",
48
- description = "What this command does",
49
- action = "my_command_function", -- Name of global Lua function to call
50
- contexts = {"normal"} -- or {"help", "prompt", "popup", "file_explorer"}
51
- })
52
-
53
- -- Define the global function
54
- function my_command_function()
55
- editor.set_status("My command executed!")
56
- end
57
- ```
58
-
59
- The `action` field should be the name of a global Lua function that will be called when the command is executed from the command palette.
60
-
61
- #### editor.set_status(message)
62
- Set the status bar message.
63
-
64
- ```lua
65
- editor.set_status("Plugin loaded successfully")
66
- ```
67
-
68
- #### editor.insert_text(buffer_id, position, text)
69
- Insert text at a specific position in a buffer.
30
+ ### virtual_buffer_demo.ts
70
31
 
71
- ```lua
72
- editor.insert_text(0, 0, "Hello, World!")
73
- ```
32
+ Demonstrates virtual buffer creation:
33
+ - Creating virtual buffers with `createVirtualBufferInSplit`
34
+ - Using text properties for embedded metadata
35
+ - Defining custom modes with keybindings
36
+ - Handling "go to" navigation from results
74
37
 
75
- #### editor.add_overlay(buffer_id, overlay_id, start, end, r, g, b, underline)
76
- Add a visual overlay (highlight/underline) to a buffer.
77
-
78
- ```lua
79
- -- Add red underline to positions 0-10 in buffer 0
80
- editor.add_overlay(0, "my-overlay", 0, 10, 255, 0, 0, true)
81
- ```
82
-
83
- #### editor.on(hook_name, callback)
84
- Register a hook callback (currently simplified).
85
-
86
- ```lua
87
- editor.on("after-file-save", function(args)
88
- print("File saved!")
89
- return true -- return false to cancel operation
90
- end)
91
- ```
38
+ ### bookmarks.ts
92
39
 
93
- #### editor.spawn(command, args, callback) or editor.spawn(command, args, options, callback)
94
- Spawn an async process and get its output.
40
+ A complete bookmark management example:
41
+ - Managing persistent state across sessions
42
+ - Creating navigation commands
43
+ - Using overlays for visual markers
95
44
 
96
- ```lua
97
- -- Simple form
98
- editor.spawn("git", {"status", "--porcelain"}, function(stdout, stderr, exit_code)
99
- editor.set_status("Git status: " .. stdout)
100
- end)
45
+ ### git_grep.ts
101
46
 
102
- -- With options (e.g., working directory)
103
- editor.spawn("ls", {"-la"}, {cwd = "/tmp"}, function(stdout, stderr, exit_code)
104
- print("Files: " .. stdout)
105
- end)
106
- ```
107
-
108
- #### editor.open_file(path) or editor.open_file({path, line, column})
109
- Open a file, optionally jumping to a specific line and column.
110
-
111
- ```lua
112
- -- Open file at start
113
- editor.open_file("src/main.rs")
114
-
115
- -- Open file and jump to line 42, column 10 (1-indexed)
116
- editor.open_file({
117
- path = "src/main.rs",
118
- line = 42,
119
- column = 10
120
- })
121
- ```
122
-
123
- This is particularly useful for implementing features like git grep, LSP go-to-definition, etc.
124
-
125
- #### editor.start_prompt(options) and editor.set_prompt_suggestions(suggestions)
126
- Create interactive prompts with hook-based event handling.
127
-
128
- ```lua
129
- -- Start a prompt
130
- editor.start_prompt({
131
- label = "Git grep: ",
132
- prompt_type = "git-grep" -- Custom identifier for hook filtering
133
- })
134
-
135
- -- React to input changes via hooks
136
- editor.on("prompt-changed", function(args)
137
- if args.prompt_type == "git-grep" then
138
- local query = args.input
139
-
140
- -- Spawn async git grep
141
- editor.spawn("git", {"grep", "-n", "--column", "-I", "--", query},
142
- function(stdout, stderr, exit_code)
143
- if exit_code == 0 then
144
- local results = parse_git_grep(stdout)
145
-
146
- -- Update suggestions
147
- editor.set_prompt_suggestions(results)
148
- end
149
- end)
150
- end
151
- end)
152
-
153
- -- Handle selection
154
- editor.on("prompt-confirmed", function(args)
155
- if args.prompt_type == "git-grep" and args.selected_index then
156
- local selected = prompt_suggestions[args.selected_index + 1] -- Lua is 1-indexed
157
- editor.open_file({
158
- path = selected.file,
159
- line = selected.line,
160
- column = selected.column
161
- })
162
- end
163
- end)
164
- ```
165
-
166
- Suggestions format:
167
- ```lua
168
- editor.set_prompt_suggestions({
169
- {
170
- text = "src/main.rs:42:10: match found here",
171
- value = "src/main.rs:42:10", -- Optional: value to use when selected
172
- description = "Path to file", -- Optional
173
- disabled = false, -- Optional: grey out this suggestion
174
- keybinding = nil -- Optional: show keyboard shortcut
175
- },
176
- -- ... more suggestions
177
- })
178
- ```
179
-
180
- This hook-based approach is simpler than callbacks and matches Emacs' extensibility model.
181
-
182
- ## Available Hooks
183
-
184
- ### File Hooks
185
- - `before-file-open` - Before a file is opened
186
- - `after-file-open` - After a file is successfully opened
187
- - `before-file-save` - Before a file is saved
188
- - `after-file-save` - After a file is saved
189
-
190
- ### Edit Hooks
191
- - `after-insert` - After text is inserted
192
- - `after-delete` - After text is deleted
193
-
194
- ### Command Hooks
195
- - `pre-command` - Before a command executes
196
- - `post-command` - After a command executes
197
-
198
- ### Prompt Hooks (NEW - Jan 2025)
199
- - `prompt-changed` - User typed/edited prompt input (args: `prompt_type`, `input`)
200
- - `prompt-confirmed` - User pressed Enter (args: `prompt_type`, `input`, `selected_index`)
201
- - `prompt-cancelled` - User pressed Escape/Ctrl+G (args: `prompt_type`, `input`)
202
-
203
- These prompt hooks enable plugins to create interactive prompts like git grep, file finders, etc.
47
+ Git grep implementation demonstrating:
48
+ - Spawning async git processes
49
+ - Parsing structured output
50
+ - Opening files at specific line:column positions
51
+ - Interactive search with prompt API
204
52
 
205
53
  ## Writing Your Own Plugin
206
54
 
207
- 1. Create a `.lua` file in the plugins directory
208
- 2. Use the API functions above to add functionality
209
- 3. The plugin will be automatically loaded when the editor starts
55
+ 1. Create a `.ts` file in the plugins directory
56
+ 2. Use the `editor` global object to access the API
57
+ 3. Register commands with `editor.registerCommand()`
58
+ 4. The plugin will be automatically loaded when the editor starts
210
59
 
211
60
  Example template:
212
61
 
213
- ```lua
214
- -- My Custom Plugin
215
-
216
- -- Register commands
217
- editor.register_command({
218
- name = "My Custom Command",
219
- description = "Does something cool",
220
- action = "none",
221
- contexts = {"normal"}
222
- })
223
-
224
- -- Add hooks if needed
225
- editor.on("after-file-save", function(args)
226
- editor.set_status("File saved - plugin notified!")
227
- return true
228
- end)
229
-
230
- -- Initialization message
231
- print("My custom plugin loaded")
232
- ```
62
+ ```typescript
63
+ /// <reference path="../types/fresh.d.ts" />
233
64
 
234
- ## Testing Plugins
65
+ // Define the command handler
66
+ globalThis.my_command = function(): void {
67
+ editor.setStatus("My command executed!");
68
+ };
235
69
 
236
- Currently, plugins are unit tested through the plugin_manager tests. Integration tests will be added in a future update.
70
+ // Register the command
71
+ editor.registerCommand(
72
+ "My Custom Command",
73
+ "Does something cool",
74
+ "my_command",
75
+ "normal"
76
+ );
77
+
78
+ // Initialization message
79
+ editor.debug("My custom plugin loaded");
80
+ ```
237
81
 
238
- ## Future Enhancements
82
+ ## Further Reading
239
83
 
240
- Planned features:
241
- - Buffer query API (get content, cursor position, etc.)
242
- - Popup API (custom dialogs, menus)
243
- - Async task spawning (for git operations, external commands)
244
- - More comprehensive hook system
245
- - WASM plugin support for multi-language plugins
84
+ - **Getting Started:** [docs/PLUGIN_DEVELOPMENT.md](../../docs/PLUGIN_DEVELOPMENT.md)
85
+ - **API Reference:** [docs/plugin-api.md](../../docs/plugin-api.md)
@@ -91,6 +91,12 @@ interface SpawnResult {
91
91
  exit_code: number;
92
92
  }
93
93
 
94
+ /** Result from spawnBackgroundProcess - just the process ID */
95
+ interface BackgroundProcessResult {
96
+ /** Unique process ID for later reference (kill, status check) */
97
+ process_id: number;
98
+ }
99
+
94
100
  /** File stat information */
95
101
  interface FileStat {
96
102
  /** Whether the path exists */
@@ -322,6 +328,13 @@ interface EditorAPI {
322
328
  * is typically first. For selection info use getAllCursors instead.
323
329
  */
324
330
  getAllCursorPositions(): number[];
331
+ /**
332
+ * Check if a background process is still running
333
+ *
334
+ * @param process_id - ID returned from spawnBackgroundProcess
335
+ * @returns true if process is running, false if not found or exited
336
+ */
337
+ isProcessRunning(#[bigint] process_id: number): boolean;
325
338
 
326
339
  // === Buffer Info Queries ===
327
340
  /**
@@ -419,7 +432,7 @@ interface EditorAPI {
419
432
  * @param priority - Priority for ordering multiple lines at same position
420
433
  * @returns true if virtual line was added
421
434
  */
422
- addVirtualLine(buffer_id: number, position: number, text: string, fg_r: number, fg_g: number, fg_b: number, bg_r: number, bg_g: number, bg_b: number, above: boolean, namespace: string, priority: number): boolean;
435
+ addVirtualLine(buffer_id: number, position: number, text: string, fg_r: number, fg_g: number, fg_b: number, bg_r: i16, bg_g: i16, bg_b: i16, above: boolean, namespace: string, priority: number): boolean;
423
436
  /**
424
437
  * Submit a transformed view stream for a viewport
425
438
  * @param buffer_id - Buffer to apply the transform to
@@ -475,6 +488,34 @@ interface EditorAPI {
475
488
  * @returns true if file was opened
476
489
  */
477
490
  openFileInSplit(split_id: number, path: string, line: number, column: number): boolean;
491
+ /**
492
+ * Spawn a long-running background process
493
+ *
494
+ * Unlike spawnProcess which waits for completion, this starts a process
495
+ * in the background and returns immediately with a process ID.
496
+ * Use killProcess(id) to terminate the process later.
497
+ * Use isProcessRunning(id) to check if it's still running.
498
+ *
499
+ * @param command - Program name (searched in PATH) or absolute path
500
+ * @param args - Command arguments (each array element is one argument)
501
+ * @param cwd - Working directory; null uses editor's cwd
502
+ * @returns Object with process_id for later reference
503
+ * @example
504
+ * const proc = await editor.spawnBackgroundProcess("asciinema", ["rec", "output.cast"]);
505
+ * // Later...
506
+ * await editor.killProcess(proc.process_id);
507
+ */
508
+ spawnBackgroundProcess(command: string, args: string[], cwd?: string | null): Promise<BackgroundProcessResult>;
509
+ /**
510
+ * Kill a background process by ID
511
+ *
512
+ * Sends SIGTERM to gracefully terminate the process.
513
+ * Returns true if the process was found and killed, false if not found.
514
+ *
515
+ * @param process_id - ID returned from spawnBackgroundProcess
516
+ * @returns true if process was killed, false if not found
517
+ */
518
+ killProcess(#[bigint] process_id: number): Promise<boolean>;
478
519
  /**
479
520
  * Send an arbitrary LSP request and receive the raw JSON response
480
521
  * @param language - Language ID (e.g., "cpp")