@fresh-editor/fresh-editor 0.1.87 → 0.1.90
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/CHANGELOG.md +69 -0
- package/package.json +1 -1
- package/plugins/audit_mode.ts +6 -13
- package/plugins/clangd_support.i18n.json +26 -26
- package/plugins/config-schema.json +205 -116
- package/plugins/csharp_support.i18n.json +52 -52
- package/plugins/csharp_support.ts +214 -41
- package/plugins/examples/bookmarks.ts +4 -10
- package/plugins/examples/hello_world.ts +3 -10
- package/plugins/find_references.i18n.json +91 -91
- package/plugins/git_log.i18n.json +182 -182
- package/plugins/git_log.ts +70 -165
- package/plugins/lib/finder.ts +19 -80
- package/plugins/lib/fresh.d.ts +124 -5
- package/plugins/live_grep.i18n.json +39 -39
- package/plugins/markdown_compose.i18n.json +13 -13
- package/plugins/merge_conflict.i18n.json +143 -143
- package/plugins/merge_conflict.ts +8 -20
- package/plugins/pkg.i18n.json +314 -0
- package/plugins/pkg.ts +2514 -0
- package/plugins/schemas/package.schema.json +192 -0
- package/plugins/schemas/theme.schema.json +815 -0
- package/plugins/search_replace.i18n.json +143 -143
- package/plugins/theme_editor.i18n.json +92 -14
- package/plugins/theme_editor.ts +5 -5
- package/themes/dracula.json +26 -5
- package/plugins/calculator.i18n.json +0 -93
- package/plugins/calculator.ts +0 -769
- package/plugins/color_highlighter.i18n.json +0 -145
- package/plugins/color_highlighter.ts +0 -306
- package/plugins/csharp-lsp.ts +0 -147
- package/plugins/examples/git_grep.ts +0 -262
- package/plugins/todo_highlighter.i18n.json +0 -184
- package/plugins/todo_highlighter.ts +0 -206
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
/// <reference path="./lib/fresh.d.ts" />
|
|
2
2
|
const editor = getEditor();
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
/**
|
|
6
5
|
* C# Language Server Support Plugin
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
* -
|
|
10
|
-
* - csharp-language-server (Roslyn-based)
|
|
11
|
-
* - OmniSharp
|
|
12
|
-
*
|
|
13
|
-
* Features:
|
|
7
|
+
* Provides comprehensive C# LSP support including:
|
|
8
|
+
* - Project root detection (finds nearest .csproj/.sln)
|
|
14
9
|
* - Auto-restore NuGet packages when opening C# files
|
|
15
|
-
* -
|
|
10
|
+
* - Handle LSP server requests (e.g., workspace/_roslyn_projectNeedsRestore)
|
|
11
|
+
* - User-friendly error handling when csharp-ls fails to start
|
|
12
|
+
* - Installation help popup with commands to install csharp-ls
|
|
16
13
|
*/
|
|
17
14
|
|
|
15
|
+
// ==================== Type Definitions ====================
|
|
16
|
+
|
|
18
17
|
interface LspServerRequestData {
|
|
19
18
|
language: string;
|
|
20
19
|
method: string;
|
|
@@ -22,6 +21,23 @@ interface LspServerRequestData {
|
|
|
22
21
|
params: string | null;
|
|
23
22
|
}
|
|
24
23
|
|
|
24
|
+
interface LspServerErrorData {
|
|
25
|
+
language: string;
|
|
26
|
+
server_command: string;
|
|
27
|
+
error_type: string;
|
|
28
|
+
message: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface LspStatusClickedData {
|
|
32
|
+
language: string;
|
|
33
|
+
has_error: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface ActionPopupResultData {
|
|
37
|
+
popup_id: string;
|
|
38
|
+
action_id: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
25
41
|
interface ProjectNeedsRestoreParams {
|
|
26
42
|
projectFilePath: string;
|
|
27
43
|
}
|
|
@@ -31,12 +47,25 @@ interface AfterFileOpenData {
|
|
|
31
47
|
buffer_id: number;
|
|
32
48
|
}
|
|
33
49
|
|
|
50
|
+
// ==================== State ====================
|
|
51
|
+
|
|
34
52
|
// Track which directories we've already restored to avoid repeated restores
|
|
35
53
|
const restoredDirectories = new Set<string>();
|
|
36
54
|
|
|
55
|
+
// Track which project roots we've already set for LSP
|
|
56
|
+
const configuredProjectRoots = new Set<string>();
|
|
57
|
+
|
|
37
58
|
// Cache whether dotnet is available (null = not checked yet)
|
|
38
59
|
let dotnetAvailable: boolean | null = null;
|
|
39
60
|
|
|
61
|
+
// Track error state for C# LSP
|
|
62
|
+
let csharpLspError: { serverCommand: string; message: string } | null = null;
|
|
63
|
+
|
|
64
|
+
// Install command for csharp-ls
|
|
65
|
+
const INSTALL_COMMAND = "dotnet tool install --global csharp-ls";
|
|
66
|
+
|
|
67
|
+
// ==================== Utility Functions ====================
|
|
68
|
+
|
|
40
69
|
/**
|
|
41
70
|
* Check if dotnet CLI is available
|
|
42
71
|
*/
|
|
@@ -59,11 +88,59 @@ async function isDotnetAvailable(): Promise<boolean> {
|
|
|
59
88
|
return dotnetAvailable;
|
|
60
89
|
}
|
|
61
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Get the directory containing the file
|
|
93
|
+
*/
|
|
94
|
+
function getDirectory(filePath: string): string {
|
|
95
|
+
return editor.pathDirname(filePath);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Find the project root by walking up directories looking for .csproj or .sln files
|
|
100
|
+
* Returns the directory containing the project file, or null if not found
|
|
101
|
+
*/
|
|
102
|
+
function findProjectRoot(startPath: string): string | null {
|
|
103
|
+
let currentDir = getDirectory(startPath);
|
|
104
|
+
const maxDepth = 20; // Prevent infinite loops
|
|
105
|
+
let depth = 0;
|
|
106
|
+
|
|
107
|
+
while (depth < maxDepth) {
|
|
108
|
+
// Check if this directory contains a .csproj or .sln file
|
|
109
|
+
try {
|
|
110
|
+
const entries = editor.readDir(currentDir);
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
if (entry.is_file) {
|
|
113
|
+
if (entry.name.endsWith(".csproj") || entry.name.endsWith(".sln")) {
|
|
114
|
+
editor.debug(`csharp_support: Found project file ${entry.name} in ${currentDir}`);
|
|
115
|
+
return currentDir;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} catch (e) {
|
|
120
|
+
// Directory read failed, stop searching
|
|
121
|
+
editor.debug(`csharp_support: Failed to read directory ${currentDir}: ${e}`);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Move up to parent directory
|
|
126
|
+
const parentDir = editor.pathDirname(currentDir);
|
|
127
|
+
if (parentDir === currentDir || parentDir === "/" || parentDir === "") {
|
|
128
|
+
// Reached root or can't go higher
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
currentDir = parentDir;
|
|
132
|
+
depth++;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
editor.debug(`csharp_support: No .csproj or .sln found for ${startPath}`);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
62
139
|
/**
|
|
63
140
|
* Run dotnet restore for a project
|
|
64
141
|
*/
|
|
65
142
|
async function restoreProject(projectPath: string): Promise<void> {
|
|
66
|
-
if (!await isDotnetAvailable()) {
|
|
143
|
+
if (!(await isDotnetAvailable())) {
|
|
67
144
|
return;
|
|
68
145
|
}
|
|
69
146
|
|
|
@@ -87,20 +164,63 @@ async function restoreProject(projectPath: string): Promise<void> {
|
|
|
87
164
|
}
|
|
88
165
|
}
|
|
89
166
|
|
|
167
|
+
// ==================== Event Handlers ====================
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Handle file open - set project root and restore packages
|
|
171
|
+
*/
|
|
172
|
+
globalThis.on_csharp_file_open = async function (data: AfterFileOpenData): Promise<void> {
|
|
173
|
+
// Only handle .cs files
|
|
174
|
+
if (!data.path.endsWith(".cs")) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
editor.debug(`csharp_support: C# file opened: ${data.path}`);
|
|
179
|
+
|
|
180
|
+
// Find the project root
|
|
181
|
+
const projectRoot = findProjectRoot(data.path);
|
|
182
|
+
|
|
183
|
+
if (projectRoot) {
|
|
184
|
+
// Set the LSP root URI if we haven't already for this project
|
|
185
|
+
if (!configuredProjectRoots.has(projectRoot)) {
|
|
186
|
+
configuredProjectRoots.add(projectRoot);
|
|
187
|
+
|
|
188
|
+
// Convert path to file:// URI
|
|
189
|
+
const rootUri = `file://${projectRoot}`;
|
|
190
|
+
editor.debug(`csharp_support: Setting LSP root URI to ${rootUri}`);
|
|
191
|
+
editor.setLspRootUri("csharp", rootUri);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Run dotnet restore if we haven't already for this directory
|
|
195
|
+
if (!restoredDirectories.has(projectRoot)) {
|
|
196
|
+
restoredDirectories.add(projectRoot);
|
|
197
|
+
editor.debug(`csharp_support: Running dotnet restore in ${projectRoot}`);
|
|
198
|
+
await restoreProject(projectRoot);
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
// No project file found - use file's directory for restore
|
|
202
|
+
const dir = getDirectory(data.path);
|
|
203
|
+
if (!restoredDirectories.has(dir)) {
|
|
204
|
+
restoredDirectories.add(dir);
|
|
205
|
+
editor.debug(`csharp_support: No project found, running dotnet restore in ${dir}`);
|
|
206
|
+
await restoreProject(dir);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Register hook for file open
|
|
212
|
+
editor.on("after_file_open", "on_csharp_file_open");
|
|
213
|
+
|
|
90
214
|
/**
|
|
91
215
|
* Handle LSP server requests from C# language servers (Roslyn-based)
|
|
92
216
|
*/
|
|
93
|
-
globalThis.on_csharp_lsp_server_request = function (
|
|
94
|
-
data: LspServerRequestData
|
|
95
|
-
): void {
|
|
217
|
+
globalThis.on_csharp_lsp_server_request = function (data: LspServerRequestData): void {
|
|
96
218
|
// Only handle requests from C# language servers
|
|
97
219
|
if (data.server_command !== "csharp-ls" && data.server_command !== "csharp-language-server") {
|
|
98
220
|
return;
|
|
99
221
|
}
|
|
100
222
|
|
|
101
|
-
editor.debug(
|
|
102
|
-
`csharp_support: Received LSP request ${data.method} from ${data.server_command}`
|
|
103
|
-
);
|
|
223
|
+
editor.debug(`csharp_support: Received LSP request ${data.method} from ${data.server_command}`);
|
|
104
224
|
|
|
105
225
|
switch (data.method) {
|
|
106
226
|
case "workspace/_roslyn_projectNeedsRestore": {
|
|
@@ -120,9 +240,7 @@ globalThis.on_csharp_lsp_server_request = function (
|
|
|
120
240
|
|
|
121
241
|
default:
|
|
122
242
|
// Log unhandled requests for debugging
|
|
123
|
-
editor.debug(
|
|
124
|
-
`csharp_support: Unhandled LSP request: ${data.method}`
|
|
125
|
-
);
|
|
243
|
+
editor.debug(`csharp_support: Unhandled LSP request: ${data.method}`);
|
|
126
244
|
}
|
|
127
245
|
};
|
|
128
246
|
|
|
@@ -130,41 +248,96 @@ globalThis.on_csharp_lsp_server_request = function (
|
|
|
130
248
|
editor.on("lsp_server_request", "on_csharp_lsp_server_request");
|
|
131
249
|
|
|
132
250
|
/**
|
|
133
|
-
*
|
|
251
|
+
* Handle LSP server errors for C#
|
|
134
252
|
*/
|
|
135
|
-
function
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
return
|
|
253
|
+
globalThis.on_csharp_lsp_server_error = function (data: LspServerErrorData): void {
|
|
254
|
+
// Only handle C# language errors
|
|
255
|
+
if (data.language !== "csharp") {
|
|
256
|
+
return;
|
|
139
257
|
}
|
|
140
|
-
|
|
141
|
-
}
|
|
258
|
+
|
|
259
|
+
editor.debug(`csharp_support: Server error - ${data.error_type}: ${data.message}`);
|
|
260
|
+
|
|
261
|
+
// Store error state for later reference
|
|
262
|
+
csharpLspError = {
|
|
263
|
+
serverCommand: data.server_command,
|
|
264
|
+
message: data.message,
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// Show a status message for immediate feedback
|
|
268
|
+
if (data.error_type === "not_found") {
|
|
269
|
+
editor.setStatus(
|
|
270
|
+
`C# LSP server '${data.server_command}' not found. Click status bar for help.`
|
|
271
|
+
);
|
|
272
|
+
} else {
|
|
273
|
+
editor.setStatus(`C# LSP error: ${data.message}`);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// Register hook for LSP server errors
|
|
278
|
+
editor.on("lsp_server_error", "on_csharp_lsp_server_error");
|
|
142
279
|
|
|
143
280
|
/**
|
|
144
|
-
*
|
|
145
|
-
* This ensures the LSP server has access to restored packages from the start
|
|
281
|
+
* Handle status bar click when there's a C# LSP error
|
|
146
282
|
*/
|
|
147
|
-
globalThis.
|
|
148
|
-
|
|
149
|
-
)
|
|
150
|
-
// Only handle .cs files
|
|
151
|
-
if (!data.path.endsWith(".cs")) {
|
|
283
|
+
globalThis.on_csharp_lsp_status_clicked = function (data: LspStatusClickedData): void {
|
|
284
|
+
// Only handle C# language clicks when there's an error
|
|
285
|
+
if (data.language !== "csharp" || !csharpLspError) {
|
|
152
286
|
return;
|
|
153
287
|
}
|
|
154
288
|
|
|
155
|
-
|
|
289
|
+
editor.debug("csharp_support: Status clicked, showing help popup");
|
|
156
290
|
|
|
157
|
-
//
|
|
158
|
-
|
|
291
|
+
// Show action popup with install options
|
|
292
|
+
editor.showActionPopup({
|
|
293
|
+
id: "csharp-lsp-help",
|
|
294
|
+
title: "C# Language Server Not Found",
|
|
295
|
+
message: `"${csharpLspError.serverCommand}" provides code completion, diagnostics, and navigation for C# files. Requires .NET SDK. Copy the command below to install it.`,
|
|
296
|
+
actions: [
|
|
297
|
+
{ id: "copy_dotnet", label: `Copy: ${INSTALL_COMMAND}` },
|
|
298
|
+
{ id: "disable", label: "Disable C# LSP" },
|
|
299
|
+
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
300
|
+
],
|
|
301
|
+
});
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
// Register hook for status bar clicks
|
|
305
|
+
editor.on("lsp_status_clicked", "on_csharp_lsp_status_clicked");
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Handle action popup results for C# LSP help
|
|
309
|
+
*/
|
|
310
|
+
globalThis.on_csharp_lsp_action_result = function (data: ActionPopupResultData): void {
|
|
311
|
+
// Only handle our popup
|
|
312
|
+
if (data.popup_id !== "csharp-lsp-help") {
|
|
159
313
|
return;
|
|
160
314
|
}
|
|
161
315
|
|
|
162
|
-
|
|
163
|
-
restoredDirectories.add(dir);
|
|
316
|
+
editor.debug(`csharp_support: Action selected - ${data.action_id}`);
|
|
164
317
|
|
|
165
|
-
|
|
166
|
-
|
|
318
|
+
switch (data.action_id) {
|
|
319
|
+
case "copy_dotnet":
|
|
320
|
+
editor.setClipboard(INSTALL_COMMAND);
|
|
321
|
+
editor.setStatus("Copied: " + INSTALL_COMMAND);
|
|
322
|
+
break;
|
|
323
|
+
|
|
324
|
+
case "disable":
|
|
325
|
+
editor.disableLspForLanguage("csharp");
|
|
326
|
+
editor.setStatus("C# LSP disabled");
|
|
327
|
+
csharpLspError = null;
|
|
328
|
+
break;
|
|
329
|
+
|
|
330
|
+
case "dismiss":
|
|
331
|
+
case "dismissed":
|
|
332
|
+
// Just close the popup without action
|
|
333
|
+
break;
|
|
334
|
+
|
|
335
|
+
default:
|
|
336
|
+
editor.debug(`csharp_support: Unknown action: ${data.action_id}`);
|
|
337
|
+
}
|
|
167
338
|
};
|
|
168
339
|
|
|
169
|
-
// Register hook for
|
|
170
|
-
editor.on("
|
|
340
|
+
// Register hook for action popup results
|
|
341
|
+
editor.on("action_popup_result", "on_csharp_lsp_action_result");
|
|
342
|
+
|
|
343
|
+
editor.debug("csharp_support: Plugin loaded");
|
|
@@ -98,16 +98,10 @@ globalThis.bookmark_add = function (): void {
|
|
|
98
98
|
|
|
99
99
|
// Add visual indicator with bookmark namespace
|
|
100
100
|
const bufferId = editor.getActiveBufferId();
|
|
101
|
-
editor.addOverlay(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
position + 1,
|
|
106
|
-
0, // Red
|
|
107
|
-
128, // Green (teal color)
|
|
108
|
-
255, // Blue
|
|
109
|
-
true // Underline
|
|
110
|
-
);
|
|
101
|
+
editor.addOverlay(bufferId, "bookmark", position, position + 1, {
|
|
102
|
+
fg: [0, 128, 255], // Teal color
|
|
103
|
+
underline: true,
|
|
104
|
+
});
|
|
111
105
|
|
|
112
106
|
editor.setStatus(`Added ${name} at ${path}:${line}:${column}`);
|
|
113
107
|
editor.debug(`Bookmark ${id} created: ${JSON.stringify(bookmark)}`);
|
|
@@ -49,16 +49,9 @@ globalThis.highlight_region = function (): void {
|
|
|
49
49
|
const end = cursorPos + 5;
|
|
50
50
|
|
|
51
51
|
// Use namespace "demo" for batch operations
|
|
52
|
-
const success = editor.addOverlay(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
start,
|
|
56
|
-
end,
|
|
57
|
-
255, // Red
|
|
58
|
-
255, // Green
|
|
59
|
-
0, // Blue (yellow highlight)
|
|
60
|
-
false // No underline
|
|
61
|
-
);
|
|
52
|
+
const success = editor.addOverlay(bufferId, "demo", start, end, {
|
|
53
|
+
fg: [255, 255, 0], // Yellow highlight
|
|
54
|
+
});
|
|
62
55
|
|
|
63
56
|
if (success) {
|
|
64
57
|
editor.setStatus(`Highlighted region ${start}-${end}`);
|