@fresh-editor/fresh-editor 0.1.7 → 0.1.10
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/README.md +36 -11
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
- package/plugins/test_view_marker.ts +0 -236
package/README.md
CHANGED
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
# Fresh
|
|
2
2
|
|
|
3
|
+
[Visit the official Fresh website](https://sinelaw.github.io/fresh/)
|
|
4
|
+
|
|
5
|
+
**[📦 Installation Instructions](#installation)**
|
|
6
|
+
|
|
3
7
|
A terminal-based text editor.
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
## Discovery & Ease of Use
|
|
10
|
+
|
|
11
|
+
Fresh is designed for discovery. It features native UIs, a full Menu system, and a powerful Command Palette. With full mouse support, transitioning from graphical editors is seamless.
|
|
12
|
+
|
|
13
|
+
## Modern Extensibility
|
|
6
14
|
|
|
7
|
-
|
|
15
|
+
Extend Fresh easily using modern tools. Plugins are written in TypeScript and run securely in a sandboxed Deno environment, providing access to a modern JavaScript ecosystem without compromising stability.
|
|
8
16
|
|
|
9
|
-
##
|
|
17
|
+
## Zero-Latency Performance
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
19
|
+
Fresh is engineered for speed. It delivers a near zero-latency experience, with text appearing instantly. The editor is designed to be light and fast, reliably opening and editing huge files up to multi-gigabyte sizes without slowdown.
|
|
20
|
+
|
|
21
|
+
## Comprehensive Feature Set
|
|
22
|
+
|
|
23
|
+
- **File Management**: open/save/new/close, file explorer, tabs, auto-revert, git file finder
|
|
24
|
+
- **Editing**: undo/redo, multi-cursor, block selection, smart indent, comments, clipboard
|
|
25
|
+
- **Search & Replace**: incremental search, find in selection, query replace, git grep
|
|
26
|
+
- **Navigation**: go to line/bracket, word movement, position history, bookmarks, error navigation
|
|
27
|
+
- **Views & Layout**: split panes, line numbers, line wrap, backgrounds, markdown preview
|
|
28
|
+
- **Language Server (LSP)**: go to definition, references, hover, code actions, rename, diagnostics, autocompletion
|
|
29
|
+
- **Productivity**: command palette, menu bar, keyboard macros, git log, diagnostics panel
|
|
30
|
+
- **Plugins & Extensibility**: TypeScript plugins, color highlighter, TODO highlighter, merge conflicts, path complete, keymaps
|
|
17
31
|
|
|
18
32
|

|
|
19
33
|

|
|
@@ -21,7 +35,19 @@ This is a completely free and open source project, not owned by any commerical c
|
|
|
21
35
|
|
|
22
36
|
## Installation
|
|
23
37
|
|
|
24
|
-
###
|
|
38
|
+
### Via npm (recommended)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install -g @fresh-editor/fresh-editor
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Via npx (for a quick test)
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx @fresh-editor/fresh-editor
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Pre-built binaries
|
|
25
51
|
|
|
26
52
|
Download the latest release for your platform from the [releases page](https://github.com/sinelaw/fresh/releases).
|
|
27
53
|
|
|
@@ -29,7 +55,6 @@ Download the latest release for your platform from the [releases page](https://g
|
|
|
29
55
|
|
|
30
56
|
```bash
|
|
31
57
|
cargo install fresh-editor
|
|
32
|
-
fresh [file]
|
|
33
58
|
```
|
|
34
59
|
|
|
35
60
|
### From source
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -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.
|
|
26
|
+
"version": "0.1.10"
|
|
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.
|
|
899
|
+
"version": "0.1.10"
|
|
900
900
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"artifactDownloadUrl": "https://github.com/sinelaw/fresh/releases/download/v0.1.
|
|
2
|
+
"artifactDownloadUrl": "https://github.com/sinelaw/fresh/releases/download/v0.1.10",
|
|
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.
|
|
95
|
+
"version": "0.1.10",
|
|
96
96
|
"volta": {
|
|
97
97
|
"node": "18.14.1",
|
|
98
98
|
"npm": "9.5.0"
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
/// <reference path="../types/fresh.d.ts" />
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Test plugin for virtual lines (Emacs-like persistent state model).
|
|
5
|
-
*
|
|
6
|
-
* This plugin demonstrates the virtual lines API by injecting header lines
|
|
7
|
-
* above content. Virtual lines are added to persistent state and rendered
|
|
8
|
-
* synchronously from memory - no view transform hooks needed.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
let activeBufferId: number | null = null;
|
|
12
|
-
const padLinesByBuffer = new Map<number, number>();
|
|
13
|
-
const interleavedModeByBuffer = new Map<number, boolean>();
|
|
14
|
-
|
|
15
|
-
const TEST_NAMESPACE = "test-view-marker";
|
|
16
|
-
|
|
17
|
-
// Define a simple mode for testing
|
|
18
|
-
editor.defineMode(
|
|
19
|
-
"test-view-marker",
|
|
20
|
-
"normal",
|
|
21
|
-
[
|
|
22
|
-
["q", "test_view_marker_close"],
|
|
23
|
-
],
|
|
24
|
-
true // read-only
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Add virtual header lines for a buffer
|
|
29
|
-
*/
|
|
30
|
-
function addTestHeaders(bufferId: number): void {
|
|
31
|
-
const padLines = padLinesByBuffer.get(bufferId) ?? 0;
|
|
32
|
-
const interleavedMode = interleavedModeByBuffer.get(bufferId) ?? false;
|
|
33
|
-
|
|
34
|
-
// Clear existing headers first
|
|
35
|
-
editor.clearVirtualTextNamespace(bufferId, TEST_NAMESPACE);
|
|
36
|
-
|
|
37
|
-
if (interleavedMode) {
|
|
38
|
-
// Interleaved mode: add a header above each source line
|
|
39
|
-
const content = "Line 1\nLine 2\nLine 3\n";
|
|
40
|
-
let byteOffset = 0;
|
|
41
|
-
let lineNum = 1;
|
|
42
|
-
|
|
43
|
-
for (const line of content.split('\n')) {
|
|
44
|
-
if (line.length === 0 && byteOffset >= content.length - 1) break;
|
|
45
|
-
|
|
46
|
-
// Add header above this line
|
|
47
|
-
editor.addVirtualLine(
|
|
48
|
-
bufferId,
|
|
49
|
-
byteOffset,
|
|
50
|
-
`── Header before line ${lineNum} ──`,
|
|
51
|
-
200, 200, 100, // Yellow-ish fg
|
|
52
|
-
-1, -1, -1, // No background
|
|
53
|
-
true, // above
|
|
54
|
-
TEST_NAMESPACE,
|
|
55
|
-
0
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
byteOffset += line.length + 1; // +1 for newline
|
|
59
|
-
lineNum++;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Also add initial header at byte 0
|
|
63
|
-
editor.addVirtualLine(
|
|
64
|
-
bufferId,
|
|
65
|
-
0,
|
|
66
|
-
"== INTERLEAVED HEADER ==",
|
|
67
|
-
255, 255, 0, // Yellow fg
|
|
68
|
-
-1, -1, -1, // No background
|
|
69
|
-
true, // above
|
|
70
|
-
TEST_NAMESPACE,
|
|
71
|
-
-1 // lower priority to appear first
|
|
72
|
-
);
|
|
73
|
-
} else {
|
|
74
|
-
// Simple mode: just one header at byte 0
|
|
75
|
-
editor.addVirtualLine(
|
|
76
|
-
bufferId,
|
|
77
|
-
0,
|
|
78
|
-
"== HEADER AT BYTE 0 ==",
|
|
79
|
-
255, 255, 0, // Yellow fg
|
|
80
|
-
-1, -1, -1, // No background
|
|
81
|
-
true, // above
|
|
82
|
-
TEST_NAMESPACE,
|
|
83
|
-
0
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
// Optionally add many pad lines (for scroll stress tests)
|
|
87
|
-
for (let i = 0; i < padLines; i++) {
|
|
88
|
-
editor.addVirtualLine(
|
|
89
|
-
bufferId,
|
|
90
|
-
0,
|
|
91
|
-
`Virtual pad ${i + 1}`,
|
|
92
|
-
180, 180, 180, // Light gray fg
|
|
93
|
-
-1, -1, -1, // No background
|
|
94
|
-
true, // above
|
|
95
|
-
TEST_NAMESPACE,
|
|
96
|
-
i + 1 // increasing priority so they appear in order after header
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
editor.debug(`[test_view_marker] added ${interleavedMode ? 'interleaved' : 'simple'} headers with ${padLines} pad lines`);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async function open_test_view_marker(padLines: number, name: string): Promise<void> {
|
|
105
|
-
const splitId = editor.getActiveSplitId();
|
|
106
|
-
|
|
107
|
-
editor.debug(
|
|
108
|
-
`[test_view_marker] opening view marker in split ${splitId} with ${padLines} pad lines`
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
// Create virtual buffer with simple hardcoded content
|
|
112
|
-
const entries: TextPropertyEntry[] = [
|
|
113
|
-
{ text: "Line 1\n", properties: { type: "content", line: 1 } },
|
|
114
|
-
{ text: "Line 2\n", properties: { type: "content", line: 2 } },
|
|
115
|
-
{ text: "Line 3\n", properties: { type: "content", line: 3 } },
|
|
116
|
-
];
|
|
117
|
-
|
|
118
|
-
const bufferId = await editor.createVirtualBufferInExistingSplit({
|
|
119
|
-
name,
|
|
120
|
-
mode: "test-view-marker",
|
|
121
|
-
read_only: true,
|
|
122
|
-
entries,
|
|
123
|
-
split_id: splitId,
|
|
124
|
-
show_line_numbers: true,
|
|
125
|
-
show_cursors: true,
|
|
126
|
-
editing_disabled: true,
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
if (bufferId !== null) {
|
|
130
|
-
activeBufferId = bufferId;
|
|
131
|
-
padLinesByBuffer.set(bufferId, padLines);
|
|
132
|
-
interleavedModeByBuffer.set(bufferId, false);
|
|
133
|
-
|
|
134
|
-
// Add virtual header lines
|
|
135
|
-
addTestHeaders(bufferId);
|
|
136
|
-
|
|
137
|
-
editor.debug(
|
|
138
|
-
`[test_view_marker] buffer created with id ${bufferId}, padLines=${padLines}`
|
|
139
|
-
);
|
|
140
|
-
editor.setStatus("Test view marker active - press q to close");
|
|
141
|
-
} else {
|
|
142
|
-
editor.debug(`[test_view_marker] failed to create buffer`);
|
|
143
|
-
editor.setStatus("Failed to create test view marker buffer");
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async function open_test_view_marker_interleaved(name: string): Promise<void> {
|
|
148
|
-
const splitId = editor.getActiveSplitId();
|
|
149
|
-
|
|
150
|
-
editor.debug(`[test_view_marker] opening interleaved view marker in split ${splitId}`);
|
|
151
|
-
|
|
152
|
-
// Create virtual buffer with simple hardcoded content
|
|
153
|
-
const entries: TextPropertyEntry[] = [
|
|
154
|
-
{ text: "Line 1\n", properties: { type: "content", line: 1 } },
|
|
155
|
-
{ text: "Line 2\n", properties: { type: "content", line: 2 } },
|
|
156
|
-
{ text: "Line 3\n", properties: { type: "content", line: 3 } },
|
|
157
|
-
];
|
|
158
|
-
|
|
159
|
-
const bufferId = await editor.createVirtualBufferInExistingSplit({
|
|
160
|
-
name,
|
|
161
|
-
mode: "test-view-marker",
|
|
162
|
-
read_only: true,
|
|
163
|
-
entries,
|
|
164
|
-
split_id: splitId,
|
|
165
|
-
show_line_numbers: true,
|
|
166
|
-
show_cursors: true,
|
|
167
|
-
editing_disabled: true,
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
if (bufferId !== null) {
|
|
171
|
-
activeBufferId = bufferId;
|
|
172
|
-
padLinesByBuffer.set(bufferId, 0);
|
|
173
|
-
interleavedModeByBuffer.set(bufferId, true);
|
|
174
|
-
|
|
175
|
-
// Add virtual header lines in interleaved mode
|
|
176
|
-
addTestHeaders(bufferId);
|
|
177
|
-
|
|
178
|
-
editor.debug(`[test_view_marker] interleaved buffer created with id ${bufferId}`);
|
|
179
|
-
editor.setStatus("Test view marker (interleaved) active - press q to close");
|
|
180
|
-
} else {
|
|
181
|
-
editor.debug(`[test_view_marker] failed to create buffer`);
|
|
182
|
-
editor.setStatus("Failed to create test view marker buffer");
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
globalThis.show_test_view_marker = async function(): Promise<void> {
|
|
187
|
-
await open_test_view_marker(0, "*test-view-marker*");
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
globalThis.show_test_view_marker_many_virtual_lines = async function(): Promise<void> {
|
|
191
|
-
await open_test_view_marker(120, "*test-view-marker-many*");
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
globalThis.show_test_view_marker_interleaved = async function(): Promise<void> {
|
|
195
|
-
await open_test_view_marker_interleaved("*test-view-marker-interleaved*");
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Close the test view marker
|
|
200
|
-
*/
|
|
201
|
-
globalThis.test_view_marker_close = function(): void {
|
|
202
|
-
if (activeBufferId !== null) {
|
|
203
|
-
// Clear virtual lines before closing
|
|
204
|
-
editor.clearVirtualTextNamespace(activeBufferId, TEST_NAMESPACE);
|
|
205
|
-
|
|
206
|
-
editor.closeBuffer(activeBufferId);
|
|
207
|
-
padLinesByBuffer.delete(activeBufferId);
|
|
208
|
-
interleavedModeByBuffer.delete(activeBufferId);
|
|
209
|
-
activeBufferId = null;
|
|
210
|
-
editor.setStatus("Test view marker closed");
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// Register command
|
|
215
|
-
editor.registerCommand(
|
|
216
|
-
"Test View Marker",
|
|
217
|
-
"Test virtual lines with header at byte 0",
|
|
218
|
-
"show_test_view_marker",
|
|
219
|
-
"normal"
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
editor.registerCommand(
|
|
223
|
-
"Test View Marker (Many Virtual Lines)",
|
|
224
|
-
"Test virtual lines with many header lines",
|
|
225
|
-
"show_test_view_marker_many_virtual_lines",
|
|
226
|
-
"normal"
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
editor.registerCommand(
|
|
230
|
-
"Test View Marker (Interleaved)",
|
|
231
|
-
"Test virtual lines with headers between each source line",
|
|
232
|
-
"show_test_view_marker_interleaved",
|
|
233
|
-
"normal"
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
editor.setStatus("Test View Marker plugin loaded (virtual lines)");
|