@fresh-editor/fresh-editor 0.1.58 → 0.1.59

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 CHANGED
@@ -1,5 +1,41 @@
1
1
  # Release Notes
2
2
 
3
+ ## 0.1.59
4
+
5
+ ### Features
6
+
7
+ * **Copy with Formatting**: Copy selected text as HTML with syntax highlighting. Works in Google Docs, Word, etc. Available via Edit menu submenu or command palette.
8
+
9
+ * **Pascal Language Support**: Auto-indentation and semantic highlighting for `.pas` and `.p` files (@casibbald).
10
+
11
+ * **Set Line Ending Command**: Change buffer line ending format (LF/CRLF/CR) via command palette.
12
+
13
+ * **Buffer Settings Commands**: Toggle auto_indent, use_tabs, and tab_size via command palette.
14
+
15
+ * **Settings UI**: Recursive dialog stack for nested arrays/maps, focus indicators, Ctrl+S to save, select-all on number input edit.
16
+
17
+ ### Bug Fixes
18
+
19
+ * **Tab Size Config**: Fixed tab_size config not being respected (#384).
20
+
21
+ * **Windows Multi-Line Paste**: Fixed CRLF paste appearing as single line (#427).
22
+
23
+ * **CRLF Highlighting**: Fixed syntax highlighting offset drift in CRLF files.
24
+
25
+ * **CRLF Cursor**: Fixed cursor invisible at end of line in CRLF mode.
26
+
27
+ * **Menu Navigation**: Keyboard navigation now skips disabled items.
28
+
29
+ * **Cut/Copy Disabled**: Menu items grayed out when no selection.
30
+
31
+ ### Internal
32
+
33
+ * Extracted CRLF helpers, consolidated TextMateHighlighter into TextMateEngine.
34
+
35
+ * Updated insta (1.45.0), deno_core (0.376.0).
36
+
37
+ ---
38
+
3
39
  ## 0.1.57
4
40
 
5
41
  ### Bug Fixes
package/README.md CHANGED
@@ -4,6 +4,8 @@ A terminal-based text editor. [Official Website →](https://sinelaw.github.io/f
4
4
 
5
5
  **[📦 Installation Instructions](#installation)**
6
6
 
7
+ **[Contributing](#contributing)**
8
+
7
9
  ## Why?
8
10
 
9
11
  Why another text editor? Fresh brings the intuitive, conventional UX of editors like VS Code and Sublime Text to the terminal.
@@ -217,6 +219,26 @@ cargo build --release
217
219
  - [Plugin Development](docs/PLUGIN_DEVELOPMENT.md)
218
220
  - [Architecture](docs/ARCHITECTURE.md)
219
221
 
222
+ ## Contributing
223
+
224
+ Thanks for contributing!
225
+
226
+ 1. **Reproduce Before Fixing**: Always include a test case that reproduces the bug (fails) without the fix, and passes with the fix. This ensures the issue is verified and prevents future regressions.
227
+
228
+ 2. **E2E Tests for New Flows**: Any new user flow or feature must include an end-to-end (e2e) test. E2E tests send keyboard/mouse events and examines the final rendered output, do not examine internal state.
229
+
230
+ 3. **No timeouts or time-sensitive tests**: Use "semantic waiting" (waiting for specific state changes/events) instead of fixed timers to ensure test stability. Wait indefinitely, don't put timeouts inside tests (cargo nextest will timeout externally).
231
+
232
+ 4. **Test isolation**: Tests should run in parallel. Use the internal clipboard mode in tests to isolate them from the host system and prevent flakiness in CI. Same for other external resources (temp files, etc. should all be isolated between tests, under a per-test temporary workdir).
233
+
234
+ 5. **Required Formatting**: All code must be formatted with `cargo fmt` before submission. PRs that fail formatting checks will not be merged.
235
+
236
+ 6. **Cross-Platform Consistency**: Avoid hard-coding newline or CRLF related logic, consider the buffer mode.
237
+
238
+ 7. **LSP**: Ensure LSP interactions follow the correct lifecycle (e.g., `didOpen` must always precede other requests to avoid server-side errors). Use the appropriate existing helpers for this pattern.
239
+
240
+ **Tip**: You can use tmux + send-keys + render-pane to script ad-hoc tests on the UI, for example when trying to reproduce an issue.
241
+
220
242
  ## License
221
243
 
222
244
  Copyright (c) Noam Lewis
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fresh-editor/fresh-editor",
3
- "version": "0.1.58",
3
+ "version": "0.1.59",
4
4
  "description": "A modern terminal-based text editor with plugin support",
5
5
  "repository": {
6
6
  "type": "git",
@@ -97,668 +97,7 @@
97
97
  },
98
98
  "menu": {
99
99
  "description": "Menu bar configuration",
100
- "$ref": "#/$defs/MenuConfig",
101
- "default": {
102
- "menus": [
103
- {
104
- "label": "File",
105
- "items": [
106
- {
107
- "label": "New File",
108
- "action": "new",
109
- "args": {},
110
- "when": null,
111
- "checkbox": null
112
- },
113
- {
114
- "label": "Open File...",
115
- "action": "open",
116
- "args": {},
117
- "when": null,
118
- "checkbox": null
119
- },
120
- {
121
- "separator": true
122
- },
123
- {
124
- "label": "Save",
125
- "action": "save",
126
- "args": {},
127
- "when": null,
128
- "checkbox": null
129
- },
130
- {
131
- "label": "Save As...",
132
- "action": "save_as",
133
- "args": {},
134
- "when": null,
135
- "checkbox": null
136
- },
137
- {
138
- "label": "Revert",
139
- "action": "revert",
140
- "args": {},
141
- "when": null,
142
- "checkbox": null
143
- },
144
- {
145
- "separator": true
146
- },
147
- {
148
- "label": "Close Buffer",
149
- "action": "close",
150
- "args": {},
151
- "when": null,
152
- "checkbox": null
153
- },
154
- {
155
- "separator": true
156
- },
157
- {
158
- "label": "Switch Project...",
159
- "action": "switch_project",
160
- "args": {},
161
- "when": null,
162
- "checkbox": null
163
- },
164
- {
165
- "label": "Quit",
166
- "action": "quit",
167
- "args": {},
168
- "when": null,
169
- "checkbox": null
170
- }
171
- ]
172
- },
173
- {
174
- "label": "Edit",
175
- "items": [
176
- {
177
- "label": "Undo",
178
- "action": "undo",
179
- "args": {},
180
- "when": null,
181
- "checkbox": null
182
- },
183
- {
184
- "label": "Redo",
185
- "action": "redo",
186
- "args": {},
187
- "when": null,
188
- "checkbox": null
189
- },
190
- {
191
- "separator": true
192
- },
193
- {
194
- "label": "Cut",
195
- "action": "cut",
196
- "args": {},
197
- "when": null,
198
- "checkbox": null
199
- },
200
- {
201
- "label": "Copy",
202
- "action": "copy",
203
- "args": {},
204
- "when": null,
205
- "checkbox": null
206
- },
207
- {
208
- "label": "Paste",
209
- "action": "paste",
210
- "args": {},
211
- "when": null,
212
- "checkbox": null
213
- },
214
- {
215
- "separator": true
216
- },
217
- {
218
- "label": "Select All",
219
- "action": "select_all",
220
- "args": {},
221
- "when": null,
222
- "checkbox": null
223
- },
224
- {
225
- "separator": true
226
- },
227
- {
228
- "label": "Find...",
229
- "action": "search",
230
- "args": {},
231
- "when": null,
232
- "checkbox": null
233
- },
234
- {
235
- "label": "Find in Selection",
236
- "action": "find_in_selection",
237
- "args": {},
238
- "when": "has_selection",
239
- "checkbox": null
240
- },
241
- {
242
- "label": "Find Next",
243
- "action": "find_next",
244
- "args": {},
245
- "when": null,
246
- "checkbox": null
247
- },
248
- {
249
- "label": "Find Previous",
250
- "action": "find_previous",
251
- "args": {},
252
- "when": null,
253
- "checkbox": null
254
- },
255
- {
256
- "label": "Replace...",
257
- "action": "query_replace",
258
- "args": {},
259
- "when": null,
260
- "checkbox": null
261
- },
262
- {
263
- "separator": true
264
- },
265
- {
266
- "label": "Delete Line",
267
- "action": "delete_line",
268
- "args": {},
269
- "when": null,
270
- "checkbox": null
271
- }
272
- ]
273
- },
274
- {
275
- "label": "View",
276
- "items": [
277
- {
278
- "label": "File Explorer",
279
- "action": "toggle_file_explorer",
280
- "args": {},
281
- "when": null,
282
- "checkbox": "file_explorer"
283
- },
284
- {
285
- "separator": true
286
- },
287
- {
288
- "label": "Line Numbers",
289
- "action": "toggle_line_numbers",
290
- "args": {},
291
- "when": null,
292
- "checkbox": "line_numbers"
293
- },
294
- {
295
- "label": "Line Wrap",
296
- "action": "toggle_line_wrap",
297
- "args": {},
298
- "when": null,
299
- "checkbox": "line_wrap"
300
- },
301
- {
302
- "label": "Mouse Support",
303
- "action": "toggle_mouse_capture",
304
- "args": {},
305
- "when": null,
306
- "checkbox": "mouse_capture"
307
- },
308
- {
309
- "separator": true
310
- },
311
- {
312
- "label": "Set Background...",
313
- "action": "set_background",
314
- "args": {},
315
- "when": null,
316
- "checkbox": null
317
- },
318
- {
319
- "label": "Set Background Blend...",
320
- "action": "set_background_blend",
321
- "args": {},
322
- "when": null,
323
- "checkbox": null
324
- },
325
- {
326
- "label": "Set Compose Width...",
327
- "action": "set_compose_width",
328
- "args": {},
329
- "when": null,
330
- "checkbox": null
331
- },
332
- {
333
- "separator": true
334
- },
335
- {
336
- "label": "Select Theme...",
337
- "action": "select_theme",
338
- "args": {},
339
- "when": null,
340
- "checkbox": null
341
- },
342
- {
343
- "label": "Settings...",
344
- "action": "open_settings",
345
- "args": {},
346
- "when": null,
347
- "checkbox": null
348
- },
349
- {
350
- "separator": true
351
- },
352
- {
353
- "label": "Split Horizontal",
354
- "action": "split_horizontal",
355
- "args": {},
356
- "when": null,
357
- "checkbox": null
358
- },
359
- {
360
- "label": "Split Vertical",
361
- "action": "split_vertical",
362
- "args": {},
363
- "when": null,
364
- "checkbox": null
365
- },
366
- {
367
- "label": "Close Split",
368
- "action": "close_split",
369
- "args": {},
370
- "when": null,
371
- "checkbox": null
372
- },
373
- {
374
- "label": "Focus Next Split",
375
- "action": "next_split",
376
- "args": {},
377
- "when": null,
378
- "checkbox": null
379
- },
380
- {
381
- "label": "Focus Previous Split",
382
- "action": "prev_split",
383
- "args": {},
384
- "when": null,
385
- "checkbox": null
386
- },
387
- {
388
- "label": "Toggle Maximize Split",
389
- "action": "toggle_maximize_split",
390
- "args": {},
391
- "when": null,
392
- "checkbox": null
393
- },
394
- {
395
- "separator": true
396
- },
397
- {
398
- "label": "Terminal",
399
- "items": [
400
- {
401
- "label": "Open Terminal",
402
- "action": "open_terminal",
403
- "args": {},
404
- "when": null,
405
- "checkbox": null
406
- },
407
- {
408
- "label": "Close Terminal",
409
- "action": "close_terminal",
410
- "args": {},
411
- "when": null,
412
- "checkbox": null
413
- },
414
- {
415
- "separator": true
416
- },
417
- {
418
- "label": "Toggle Keyboard Capture",
419
- "action": "toggle_keyboard_capture",
420
- "args": {},
421
- "when": null,
422
- "checkbox": null
423
- }
424
- ]
425
- },
426
- {
427
- "separator": true
428
- },
429
- {
430
- "label": "Keybinding Style",
431
- "items": [
432
- {
433
- "label": "Default",
434
- "action": "switch_keybinding_map",
435
- "args": {
436
- "map": "default"
437
- },
438
- "when": null,
439
- "checkbox": null
440
- },
441
- {
442
- "label": "Emacs",
443
- "action": "switch_keybinding_map",
444
- "args": {
445
- "map": "emacs"
446
- },
447
- "when": null,
448
- "checkbox": null
449
- },
450
- {
451
- "label": "VSCode",
452
- "action": "switch_keybinding_map",
453
- "args": {
454
- "map": "vscode"
455
- },
456
- "when": null,
457
- "checkbox": null
458
- }
459
- ]
460
- }
461
- ]
462
- },
463
- {
464
- "label": "Selection",
465
- "items": [
466
- {
467
- "label": "Select All",
468
- "action": "select_all",
469
- "args": {},
470
- "when": null,
471
- "checkbox": null
472
- },
473
- {
474
- "label": "Select Word",
475
- "action": "select_word",
476
- "args": {},
477
- "when": null,
478
- "checkbox": null
479
- },
480
- {
481
- "label": "Select Line",
482
- "action": "select_line",
483
- "args": {},
484
- "when": null,
485
- "checkbox": null
486
- },
487
- {
488
- "label": "Expand Selection",
489
- "action": "expand_selection",
490
- "args": {},
491
- "when": null,
492
- "checkbox": null
493
- },
494
- {
495
- "separator": true
496
- },
497
- {
498
- "label": "Add Cursor Above",
499
- "action": "add_cursor_above",
500
- "args": {},
501
- "when": null,
502
- "checkbox": null
503
- },
504
- {
505
- "label": "Add Cursor Below",
506
- "action": "add_cursor_below",
507
- "args": {},
508
- "when": null,
509
- "checkbox": null
510
- },
511
- {
512
- "label": "Add Cursor at Next Match",
513
- "action": "add_cursor_next_match",
514
- "args": {},
515
- "when": null,
516
- "checkbox": null
517
- },
518
- {
519
- "label": "Remove Secondary Cursors",
520
- "action": "remove_secondary_cursors",
521
- "args": {},
522
- "when": null,
523
- "checkbox": null
524
- }
525
- ]
526
- },
527
- {
528
- "label": "Go",
529
- "items": [
530
- {
531
- "label": "Go to Line...",
532
- "action": "goto_line",
533
- "args": {},
534
- "when": null,
535
- "checkbox": null
536
- },
537
- {
538
- "label": "Go to Definition",
539
- "action": "lsp_goto_definition",
540
- "args": {},
541
- "when": null,
542
- "checkbox": null
543
- },
544
- {
545
- "label": "Find References",
546
- "action": "lsp_references",
547
- "args": {},
548
- "when": null,
549
- "checkbox": null
550
- },
551
- {
552
- "separator": true
553
- },
554
- {
555
- "label": "Next Buffer",
556
- "action": "next_buffer",
557
- "args": {},
558
- "when": null,
559
- "checkbox": null
560
- },
561
- {
562
- "label": "Previous Buffer",
563
- "action": "prev_buffer",
564
- "args": {},
565
- "when": null,
566
- "checkbox": null
567
- },
568
- {
569
- "separator": true
570
- },
571
- {
572
- "label": "Command Palette...",
573
- "action": "command_palette",
574
- "args": {},
575
- "when": null,
576
- "checkbox": null
577
- }
578
- ]
579
- },
580
- {
581
- "label": "LSP",
582
- "items": [
583
- {
584
- "label": "Show Hover Info",
585
- "action": "lsp_hover",
586
- "args": {},
587
- "when": "lsp_available",
588
- "checkbox": null
589
- },
590
- {
591
- "label": "Go to Definition",
592
- "action": "lsp_goto_definition",
593
- "args": {},
594
- "when": "lsp_available",
595
- "checkbox": null
596
- },
597
- {
598
- "label": "Find References",
599
- "action": "lsp_references",
600
- "args": {},
601
- "when": "lsp_available",
602
- "checkbox": null
603
- },
604
- {
605
- "label": "Rename Symbol",
606
- "action": "lsp_rename",
607
- "args": {},
608
- "when": "lsp_available",
609
- "checkbox": null
610
- },
611
- {
612
- "separator": true
613
- },
614
- {
615
- "label": "Show Completions",
616
- "action": "lsp_completion",
617
- "args": {},
618
- "when": "lsp_available",
619
- "checkbox": null
620
- },
621
- {
622
- "label": "Show Signature Help",
623
- "action": "lsp_signature_help",
624
- "args": {},
625
- "when": "lsp_available",
626
- "checkbox": null
627
- },
628
- {
629
- "label": "Code Actions",
630
- "action": "lsp_code_actions",
631
- "args": {},
632
- "when": "lsp_available",
633
- "checkbox": null
634
- },
635
- {
636
- "separator": true
637
- },
638
- {
639
- "label": "Toggle Inlay Hints",
640
- "action": "toggle_inlay_hints",
641
- "args": {},
642
- "when": "lsp_available",
643
- "checkbox": null
644
- },
645
- {
646
- "label": "Toggle Mouse Hover",
647
- "action": "toggle_mouse_hover",
648
- "args": {},
649
- "when": null,
650
- "checkbox": "mouse_hover"
651
- },
652
- {
653
- "separator": true
654
- },
655
- {
656
- "label": "Restart Server",
657
- "action": "lsp_restart",
658
- "args": {},
659
- "when": null,
660
- "checkbox": null
661
- },
662
- {
663
- "label": "Stop Server",
664
- "action": "lsp_stop",
665
- "args": {},
666
- "when": null,
667
- "checkbox": null
668
- }
669
- ]
670
- },
671
- {
672
- "label": "Explorer",
673
- "items": [
674
- {
675
- "label": "New File",
676
- "action": "file_explorer_new_file",
677
- "args": {},
678
- "when": "file_explorer_focused",
679
- "checkbox": null
680
- },
681
- {
682
- "label": "New Folder",
683
- "action": "file_explorer_new_directory",
684
- "args": {},
685
- "when": "file_explorer_focused",
686
- "checkbox": null
687
- },
688
- {
689
- "separator": true
690
- },
691
- {
692
- "label": "Open",
693
- "action": "file_explorer_open",
694
- "args": {},
695
- "when": "file_explorer_focused",
696
- "checkbox": null
697
- },
698
- {
699
- "label": "Rename",
700
- "action": "file_explorer_rename",
701
- "args": {},
702
- "when": "file_explorer_focused",
703
- "checkbox": null
704
- },
705
- {
706
- "label": "Delete",
707
- "action": "file_explorer_delete",
708
- "args": {},
709
- "when": "file_explorer_focused",
710
- "checkbox": null
711
- },
712
- {
713
- "separator": true
714
- },
715
- {
716
- "label": "Refresh",
717
- "action": "file_explorer_refresh",
718
- "args": {},
719
- "when": "file_explorer_focused",
720
- "checkbox": null
721
- },
722
- {
723
- "separator": true
724
- },
725
- {
726
- "label": "Show Hidden Files",
727
- "action": "file_explorer_toggle_hidden",
728
- "args": {},
729
- "when": "file_explorer",
730
- "checkbox": "file_explorer_show_hidden"
731
- },
732
- {
733
- "label": "Show Gitignored Files",
734
- "action": "file_explorer_toggle_gitignored",
735
- "args": {},
736
- "when": "file_explorer",
737
- "checkbox": "file_explorer_show_gitignored"
738
- }
739
- ]
740
- },
741
- {
742
- "label": "Help",
743
- "items": [
744
- {
745
- "label": "Show Fresh Manual",
746
- "action": "show_help",
747
- "args": {},
748
- "when": null,
749
- "checkbox": null
750
- },
751
- {
752
- "label": "Keyboard Shortcuts",
753
- "action": "keyboard_shortcuts",
754
- "args": {},
755
- "when": null,
756
- "checkbox": null
757
- }
758
- ]
759
- }
760
- ]
761
- }
100
+ "$ref": "#/$defs/MenuConfig"
762
101
  }
763
102
  },
764
103
  "$defs": {
@@ -1104,6 +443,16 @@
1104
443
  "description": "Whether pressing Tab should insert a tab character instead of spaces.\nDefaults to false (insert spaces based on tab_size).\nSet to true for languages like Go and Makefile that require tabs.",
1105
444
  "type": "boolean",
1106
445
  "default": false
446
+ },
447
+ "tab_size": {
448
+ "description": "Tab size (number of spaces per tab) for this language.\nIf not specified, falls back to the global editor.tab_size setting.",
449
+ "type": [
450
+ "integer",
451
+ "null"
452
+ ],
453
+ "format": "uint",
454
+ "minimum": 0,
455
+ "default": null
1107
456
  }
1108
457
  }
1109
458
  },
@@ -1307,6 +656,22 @@
1307
656
  "items"
1308
657
  ]
1309
658
  },
659
+ {
660
+ "description": "A dynamic submenu whose items are generated at runtime\nThe `source` field specifies what to generate (e.g., \"themes\")",
661
+ "type": "object",
662
+ "properties": {
663
+ "label": {
664
+ "type": "string"
665
+ },
666
+ "source": {
667
+ "type": "string"
668
+ }
669
+ },
670
+ "required": [
671
+ "label",
672
+ "source"
673
+ ]
674
+ },
1310
675
  {
1311
676
  "description": "A disabled info label (no action)",
1312
677
  "type": "object",