@nocturnium/svelte-ide 1.0.6 → 1.1.0

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.
@@ -510,10 +510,22 @@
510
510
  if (!folding || !editorState) return;
511
511
  foldManager.expandAll();
512
512
  const analyzer = getSemanticAnalyzer();
513
- const regions = analyzer.analyze(editorState.lines, language);
514
- for (const category of preset.hide) {
515
- for (const region of analyzer.getByCategory(regions, category)) {
516
- foldManager.collapse(region.startLine);
513
+ const semanticRegions = analyzer.analyze(editorState.lines, language);
514
+ const foldRegions = foldManager.getRegions();
515
+
516
+ // Semantic region boundaries don't always line up exactly with bracket-fold
517
+ // headers — a function's foldable `{` can sit a line below its doc-commented
518
+ // header, and a hidden category (e.g. `private`, `error-handling`) may cover
519
+ // several nested blocks. So collapse every foldable block whose header falls
520
+ // within a hidden semantic region's range, rather than requiring an exact
521
+ // header-line match (which silently folded almost nothing). collapse() is
522
+ // idempotent, so collapsing the same header twice is harmless.
523
+ for (const region of semanticRegions) {
524
+ if (!preset.hide.includes(region.category)) continue;
525
+ for (const fold of foldRegions) {
526
+ if (fold.startLine >= region.startLine && fold.startLine <= region.endLine) {
527
+ foldManager.collapse(fold.startLine);
528
+ }
517
529
  }
518
530
  }
519
531
  }
@@ -18,7 +18,7 @@ export interface FoldRegion {
18
18
  /** Indentation level (for nested folds) */
19
19
  level: number;
20
20
  /** Type of fold region */
21
- type: 'bracket' | 'indentation' | 'region' | 'comment';
21
+ type: 'bracket' | 'indentation' | 'region' | 'comment' | 'import';
22
22
  /** Whether this region is currently collapsed */
23
23
  collapsed: boolean;
24
24
  }
@@ -34,12 +34,11 @@ export interface FoldingConfig {
34
34
  regions: boolean;
35
35
  /** Enable multi-line comment folding */
36
36
  comments: boolean;
37
+ /** Enable folding a run of consecutive import statements */
38
+ imports: boolean;
37
39
  /** Minimum lines for a foldable region */
38
40
  minLines: number;
39
41
  }
40
- /**
41
- * Detect all fold regions in a document
42
- */
43
42
  export declare function detectFoldRegions(lines: readonly Line[], language?: string, config?: Partial<FoldingConfig>): FoldRegion[];
44
43
  /**
45
44
  * Fold state manager
@@ -11,6 +11,7 @@ const DEFAULT_CONFIG = {
11
11
  indentation: true,
12
12
  regions: true,
13
13
  comments: true,
14
+ imports: true,
14
15
  minLines: 2
15
16
  };
16
17
  /**
@@ -424,6 +425,38 @@ function detectCommentFolds(lines, minLines = 2) {
424
425
  /**
425
426
  * Detect all fold regions in a document
426
427
  */
428
+ /**
429
+ * Detect a fold region for each run of consecutive import statements. Import
430
+ * groups have no braces of their own, so without this an editor (and the
431
+ * "fold imports" semantic preset) can't collapse them.
432
+ */
433
+ function detectImportFolds(lines, minLines = 2) {
434
+ const regions = [];
435
+ // ES `import ... from`, side-effect `import '...'`, and Python `from x import`.
436
+ const isImportLine = (text) => /^\s*import\b/.test(text) || /^\s*from\s+\S+\s+import\b/.test(text);
437
+ let start = -1;
438
+ for (let i = 0; i <= lines.length; i++) {
439
+ const isImport = i < lines.length && isImportLine(lines[i].text);
440
+ if (isImport) {
441
+ if (start === -1)
442
+ start = i;
443
+ }
444
+ else if (start !== -1) {
445
+ const end = i - 1;
446
+ if (end - start + 1 >= minLines) {
447
+ regions.push({
448
+ startLine: start,
449
+ endLine: end,
450
+ level: 0,
451
+ type: 'import',
452
+ collapsed: false
453
+ });
454
+ }
455
+ start = -1;
456
+ }
457
+ }
458
+ return regions;
459
+ }
427
460
  export function detectFoldRegions(lines, language = 'plaintext', config = {}) {
428
461
  const cfg = { ...DEFAULT_CONFIG, ...config };
429
462
  const allRegions = [];
@@ -459,6 +492,9 @@ export function detectFoldRegions(lines, language = 'plaintext', config = {}) {
459
492
  if (cfg.comments) {
460
493
  allRegions.push(...detectCommentFolds(lines, cfg.minLines));
461
494
  }
495
+ if (cfg.imports) {
496
+ allRegions.push(...detectImportFolds(lines, cfg.minLines));
497
+ }
462
498
  // Sort by start line, then by length (longer regions first for nesting)
463
499
  allRegions.sort((a, b) => {
464
500
  if (a.startLine !== b.startLine) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocturnium/svelte-ide",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "Svelte 5 code editor and IDE building blocks — custom editor, syntax highlighting, code folding, multi-cursor, LSP client, and optional realtime collaboration.",
5
5
  "author": "Nocturnium & Jordan Dziat <hello@nocturnium.ai> (https://nocturnium.ai)",
6
6
  "license": "MIT",