CodeMirror 6 template folding: foldAll

Add a command `foldAll` using CM6's default keymap.

Bug: T30684
Change-Id: I2e26e5c0c00b23086e390d4ca5ab8c68cff73640
This commit is contained in:
bhsd 2024-03-09 14:25:42 +08:00
parent f1e81a55e2
commit 351d24d7a4
2 changed files with 38 additions and 2 deletions

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
import { showTooltip, keymap, Tooltip, KeyBinding } from '@codemirror/view';
import { StateField, Extension, EditorState } from '@codemirror/state';
import { foldEffect, ensureSyntaxTree, foldedRanges, unfoldAll, unfoldEffect, codeFolding } from '@codemirror/language';
import { foldEffect, syntaxTree, ensureSyntaxTree, foldedRanges, unfoldAll, unfoldEffect, codeFolding } from '@codemirror/language';
import { SyntaxNode, Tree } from '@lezer/common';
import { mwModeConfig as modeConfig } from './codemirror.mode.mediawiki.config';
@ -218,6 +218,42 @@ const foldKeymap = [
return false;
}
},
{
// Fold all templates in the document
key: 'Ctrl-Alt-[',
run( view ) {
const { state } = view,
tree = syntaxTree( state ),
effects = [];
/** The rightmost position of all selections, to be updated with folding */
let anchor = Math.max( ...state.selection.ranges.map( ( { to } ) => to ) ),
node = tree.topNode.firstChild;
while ( node ) {
const range = foldable( state, node, tree );
if ( range ) {
effects.push( foldEffect.of( range ) );
const { from, to } = range;
node = tree.resolve( to, 1 );
if ( from <= anchor && to > anchor ) {
// Update the anchor with the end of the last folded range
anchor = to;
}
continue;
}
node = node.nextSibling;
}
if ( effects.length > 0 ) {
const dom = view.dom.querySelector( '.cm-tooltip-fold' );
if ( dom ) {
dom.remove();
}
// Fold the template(s) and update the cursor position
view.dispatch( { effects, selection: { anchor } } );
return true;
}
return false;
}
},
{ key: 'Ctrl-Alt-]', run: unfoldAll }
];