import { IndentContext, getIndentUnit, getIndentation, indentString, indentUnit, matchBrackets, syntaxTree } from "./chunk-D63OSQ34.js"; import { Direction, EditorView } from "./chunk-LORPBXGU.js"; import { Annotation, ChangeDesc, ChangeSet, CharCategory, EditorSelection, Facet, StateEffect, StateField, Text, Transaction, combineConfig, countColumn, findClusterBreak } from "./chunk-MKFMOIK6.js"; import { NodeProp } from "./chunk-BSVZPYOD.js"; // node_modules/@codemirror/commands/dist/index.js var toggleComment = (target) => { let { state } = target, line = state.doc.lineAt(state.selection.main.from), config = getConfig(target.state, line.from); return config.line ? toggleLineComment(target) : config.block ? toggleBlockCommentByLine(target) : false; }; function command(f, option) { return ({ state, dispatch }) => { if (state.readOnly) return false; let tr = f(option, state); if (!tr) return false; dispatch(state.update(tr)); return true; }; } var toggleLineComment = command( changeLineComment, 0 /* CommentOption.Toggle */ ); var lineComment = command( changeLineComment, 1 /* CommentOption.Comment */ ); var lineUncomment = command( changeLineComment, 2 /* CommentOption.Uncomment */ ); var toggleBlockComment = command( changeBlockComment, 0 /* CommentOption.Toggle */ ); var blockComment = command( changeBlockComment, 1 /* CommentOption.Comment */ ); var blockUncomment = command( changeBlockComment, 2 /* CommentOption.Uncomment */ ); var toggleBlockCommentByLine = command( (o, s) => changeBlockComment(o, s, selectedLineRanges(s)), 0 /* CommentOption.Toggle */ ); function getConfig(state, pos) { let data = state.languageDataAt("commentTokens", pos); return data.length ? data[0] : {}; } var SearchMargin = 50; function findBlockComment(state, { open, close }, from, to) { let textBefore = state.sliceDoc(from - SearchMargin, from); let textAfter = state.sliceDoc(to, to + SearchMargin); let spaceBefore = /\s*$/.exec(textBefore)[0].length, spaceAfter = /^\s*/.exec(textAfter)[0].length; let beforeOff = textBefore.length - spaceBefore; if (textBefore.slice(beforeOff - open.length, beforeOff) == open && textAfter.slice(spaceAfter, spaceAfter + close.length) == close) { return { open: { pos: from - spaceBefore, margin: spaceBefore && 1 }, close: { pos: to + spaceAfter, margin: spaceAfter && 1 } }; } let startText, endText; if (to - from <= 2 * SearchMargin) { startText = endText = state.sliceDoc(from, to); } else { startText = state.sliceDoc(from, from + SearchMargin); endText = state.sliceDoc(to - SearchMargin, to); } let startSpace = /^\s*/.exec(startText)[0].length, endSpace = /\s*$/.exec(endText)[0].length; let endOff = endText.length - endSpace - close.length; if (startText.slice(startSpace, startSpace + open.length) == open && endText.slice(endOff, endOff + close.length) == close) { return { open: { pos: from + startSpace + open.length, margin: /\s/.test(startText.charAt(startSpace + open.length)) ? 1 : 0 }, close: { pos: to - endSpace - close.length, margin: /\s/.test(endText.charAt(endOff - 1)) ? 1 : 0 } }; } return null; } function selectedLineRanges(state) { let ranges = []; for (let r of state.selection.ranges) { let fromLine = state.doc.lineAt(r.from); let toLine = r.to <= fromLine.to ? fromLine : state.doc.lineAt(r.to); let last = ranges.length - 1; if (last >= 0 && ranges[last].to > fromLine.from) ranges[last].to = toLine.to; else ranges.push({ from: fromLine.from + /^\s*/.exec(fromLine.text)[0].length, to: toLine.to }); } return ranges; } function changeBlockComment(option, state, ranges = state.selection.ranges) { let tokens = ranges.map((r) => getConfig(state, r.from).block); if (!tokens.every((c) => c)) return null; let comments = ranges.map((r, i) => findBlockComment(state, tokens[i], r.from, r.to)); if (option != 2 && !comments.every((c) => c)) { return { changes: state.changes(ranges.map((range, i) => { if (comments[i]) return []; return [{ from: range.from, insert: tokens[i].open + " " }, { from: range.to, insert: " " + tokens[i].close }]; })) }; } else if (option != 1 && comments.some((c) => c)) { let changes = []; for (let i = 0, comment; i < comments.length; i++) if (comment = comments[i]) { let token = tokens[i], { open, close } = comment; changes.push({ from: open.pos - token.open.length, to: open.pos + open.margin }, { from: close.pos - close.margin, to: close.pos + token.close.length }); } return { changes }; } return null; } function changeLineComment(option, state, ranges = state.selection.ranges) { let lines = []; let prevLine = -1; for (let { from, to } of ranges) { let startI = lines.length, minIndent = 1e9; let token = getConfig(state, from).line; if (!token) continue; for (let pos = from; pos <= to; ) { let line = state.doc.lineAt(pos); if (line.from > prevLine && (from == to || to > line.from)) { prevLine = line.from; let indent = /^\s*/.exec(line.text)[0].length; let empty = indent == line.length; let comment = line.text.slice(indent, indent + token.length) == token ? indent : -1; if (indent < line.text.length && indent < minIndent) minIndent = indent; lines.push({ line, comment, token, indent, empty, single: false }); } pos = line.to + 1; } if (minIndent < 1e9) { for (let i = startI; i < lines.length; i++) if (lines[i].indent < lines[i].line.text.length) lines[i].indent = minIndent; } if (lines.length == startI + 1) lines[startI].single = true; } if (option != 2 && lines.some((l) => l.comment < 0 && (!l.empty || l.single))) { let changes = []; for (let { line, token, indent, empty, single } of lines) if (single || !empty) changes.push({ from: line.from + indent, insert: token + " " }); let changeSet = state.changes(changes); return { changes: changeSet, selection: state.selection.map(changeSet, 1) }; } else if (option != 1 && lines.some((l) => l.comment >= 0)) { let changes = []; for (let { line, comment, token } of lines) if (comment >= 0) { let from = line.from + comment, to = from + token.length; if (line.text[to - line.from] == " ") to++; changes.push({ from, to }); } return { changes }; } return null; } var fromHistory = Annotation.define(); var isolateHistory = Annotation.define(); var invertedEffects = Facet.define(); var historyConfig = Facet.define({ combine(configs) { return combineConfig(configs, { minDepth: 100, newGroupDelay: 500, joinToEvent: (_t, isAdjacent2) => isAdjacent2 }, { minDepth: Math.max, newGroupDelay: Math.min, joinToEvent: (a, b) => (tr, adj) => a(tr, adj) || b(tr, adj) }); } }); function changeEnd(changes) { let end = 0; changes.iterChangedRanges((_, to) => end = to); return end; } var historyField_ = StateField.define({ create() { return HistoryState.empty; }, update(state, tr) { let config = tr.state.facet(historyConfig); let fromHist = tr.annotation(fromHistory); if (fromHist) { let selection = tr.docChanged ? EditorSelection.single(changeEnd(tr.changes)) : void 0; let item = HistEvent.fromTransaction(tr, selection), from = fromHist.side; let other = from == 0 ? state.undone : state.done; if (item) other = updateBranch(other, other.length, config.minDepth, item); else other = addSelection(other, tr.startState.selection); return new HistoryState(from == 0 ? fromHist.rest : other, from == 0 ? other : fromHist.rest); } let isolate = tr.annotation(isolateHistory); if (isolate == "full" || isolate == "before") state = state.isolate(); if (tr.annotation(Transaction.addToHistory) === false) return !tr.changes.empty ? state.addMapping(tr.changes.desc) : state; let event = HistEvent.fromTransaction(tr); let time = tr.annotation(Transaction.time), userEvent = tr.annotation(Transaction.userEvent); if (event) state = state.addChanges(event, time, userEvent, config, tr); else if (tr.selection) state = state.addSelection(tr.startState.selection, time, userEvent, config.newGroupDelay); if (isolate == "full" || isolate == "after") state = state.isolate(); return state; }, toJSON(value) { return { done: value.done.map((e) => e.toJSON()), undone: value.undone.map((e) => e.toJSON()) }; }, fromJSON(json) { return new HistoryState(json.done.map(HistEvent.fromJSON), json.undone.map(HistEvent.fromJSON)); } }); function history(config = {}) { return [ historyField_, historyConfig.of(config), EditorView.domEventHandlers({ beforeinput(e, view) { let command2 = e.inputType == "historyUndo" ? undo : e.inputType == "historyRedo" ? redo : null; if (!command2) return false; e.preventDefault(); return command2(view); } }) ]; } var historyField = historyField_; function cmd(side, selection) { return function({ state, dispatch }) { if (!selection && state.readOnly) return false; let historyState = state.field(historyField_, false); if (!historyState) return false; let tr = historyState.pop(side, state, selection); if (!tr) return false; dispatch(tr); return true; }; } var undo = cmd(0, false); var redo = cmd(1, false); var undoSelection = cmd(0, true); var redoSelection = cmd(1, true); function depth(side) { return function(state) { let histState = state.field(historyField_, false); if (!histState) return 0; let branch = side == 0 ? histState.done : histState.undone; return branch.length - (branch.length && !branch[0].changes ? 1 : 0); }; } var undoDepth = depth( 0 /* BranchName.Done */ ); var redoDepth = depth( 1 /* BranchName.Undone */ ); var HistEvent = class _HistEvent { constructor(changes, effects, mapped, startSelection, selectionsAfter) { this.changes = changes; this.effects = effects; this.mapped = mapped; this.startSelection = startSelection; this.selectionsAfter = selectionsAfter; } setSelAfter(after) { return new _HistEvent(this.changes, this.effects, this.mapped, this.startSelection, after); } toJSON() { var _a, _b, _c; return { changes: (_a = this.changes) === null || _a === void 0 ? void 0 : _a.toJSON(), mapped: (_b = this.mapped) === null || _b === void 0 ? void 0 : _b.toJSON(), startSelection: (_c = this.startSelection) === null || _c === void 0 ? void 0 : _c.toJSON(), selectionsAfter: this.selectionsAfter.map((s) => s.toJSON()) }; } static fromJSON(json) { return new _HistEvent(json.changes && ChangeSet.fromJSON(json.changes), [], json.mapped && ChangeDesc.fromJSON(json.mapped), json.startSelection && EditorSelection.fromJSON(json.startSelection), json.selectionsAfter.map(EditorSelection.fromJSON)); } // This does not check `addToHistory` and such, it assumes the // transaction needs to be converted to an item. Returns null when // there are no changes or effects in the transaction. static fromTransaction(tr, selection) { let effects = none; for (let invert of tr.startState.facet(invertedEffects)) { let result = invert(tr); if (result.length) effects = effects.concat(result); } if (!effects.length && tr.changes.empty) return null; return new _HistEvent(tr.changes.invert(tr.startState.doc), effects, void 0, selection || tr.startState.selection, none); } static selection(selections) { return new _HistEvent(void 0, none, void 0, void 0, selections); } }; function updateBranch(branch, to, maxLen, newEvent) { let start = to + 1 > maxLen + 20 ? to - maxLen - 1 : 0; let newBranch = branch.slice(start, to); newBranch.push(newEvent); return newBranch; } function isAdjacent(a, b) { let ranges = [], isAdjacent2 = false; a.iterChangedRanges((f, t) => ranges.push(f, t)); b.iterChangedRanges((_f, _t, f, t) => { for (let i = 0; i < ranges.length; ) { let from = ranges[i++], to = ranges[i++]; if (t >= from && f <= to) isAdjacent2 = true; } }); return isAdjacent2; } function eqSelectionShape(a, b) { return a.ranges.length == b.ranges.length && a.ranges.filter((r, i) => r.empty != b.ranges[i].empty).length === 0; } function conc(a, b) { return !a.length ? b : !b.length ? a : a.concat(b); } var none = []; var MaxSelectionsPerEvent = 200; function addSelection(branch, selection) { if (!branch.length) { return [HistEvent.selection([selection])]; } else { let lastEvent = branch[branch.length - 1]; let sels = lastEvent.selectionsAfter.slice(Math.max(0, lastEvent.selectionsAfter.length - MaxSelectionsPerEvent)); if (sels.length && sels[sels.length - 1].eq(selection)) return branch; sels.push(selection); return updateBranch(branch, branch.length - 1, 1e9, lastEvent.setSelAfter(sels)); } } function popSelection(branch) { let last = branch[branch.length - 1]; let newBranch = branch.slice(); newBranch[branch.length - 1] = last.setSelAfter(last.selectionsAfter.slice(0, last.selectionsAfter.length - 1)); return newBranch; } function addMappingToBranch(branch, mapping) { if (!branch.length) return branch; let length = branch.length, selections = none; while (length) { let event = mapEvent(branch[length - 1], mapping, selections); if (event.changes && !event.changes.empty || event.effects.length) { let result = branch.slice(0, length); result[length - 1] = event; return result; } else { mapping = event.mapped; length--; selections = event.selectionsAfter; } } return selections.length ? [HistEvent.selection(selections)] : none; } function mapEvent(event, mapping, extraSelections) { let selections = conc(event.selectionsAfter.length ? event.selectionsAfter.map((s) => s.map(mapping)) : none, extraSelections); if (!event.changes) return HistEvent.selection(selections); let mappedChanges = event.changes.map(mapping), before = mapping.mapDesc(event.changes, true); let fullMapping = event.mapped ? event.mapped.composeDesc(before) : before; return new HistEvent(mappedChanges, StateEffect.mapEffects(event.effects, mapping), fullMapping, event.startSelection.map(before), selections); } var joinableUserEvent = /^(input\.type|delete)($|\.)/; var HistoryState = class _HistoryState { constructor(done, undone, prevTime = 0, prevUserEvent = void 0) { this.done = done; this.undone = undone; this.prevTime = prevTime; this.prevUserEvent = prevUserEvent; } isolate() { return this.prevTime ? new _HistoryState(this.done, this.undone) : this; } addChanges(event, time, userEvent, config, tr) { let done = this.done, lastEvent = done[done.length - 1]; if (lastEvent && lastEvent.changes && !lastEvent.changes.empty && event.changes && (!userEvent || joinableUserEvent.test(userEvent)) && (!lastEvent.selectionsAfter.length && time - this.prevTime < config.newGroupDelay && config.joinToEvent(tr, isAdjacent(lastEvent.changes, event.changes)) || // For compose (but not compose.start) events, always join with previous event userEvent == "input.type.compose")) { done = updateBranch(done, done.length - 1, config.minDepth, new HistEvent(event.changes.compose(lastEvent.changes), conc(event.effects, lastEvent.effects), lastEvent.mapped, lastEvent.startSelection, none)); } else { done = updateBranch(done, done.length, config.minDepth, event); } return new _HistoryState(done, none, time, userEvent); } addSelection(selection, time, userEvent, newGroupDelay) { let last = this.done.length ? this.done[this.done.length - 1].selectionsAfter : none; if (last.length > 0 && time - this.prevTime < newGroupDelay && userEvent == this.prevUserEvent && userEvent && /^select($|\.)/.test(userEvent) && eqSelectionShape(last[last.length - 1], selection)) return this; return new _HistoryState(addSelection(this.done, selection), this.undone, time, userEvent); } addMapping(mapping) { return new _HistoryState(addMappingToBranch(this.done, mapping), addMappingToBranch(this.undone, mapping), this.prevTime, this.prevUserEvent); } pop(side, state, selection) { let branch = side == 0 ? this.done : this.undone; if (branch.length == 0) return null; let event = branch[branch.length - 1]; if (selection && event.selectionsAfter.length) { return state.update({ selection: event.selectionsAfter[event.selectionsAfter.length - 1], annotations: fromHistory.of({ side, rest: popSelection(branch) }), userEvent: side == 0 ? "select.undo" : "select.redo", scrollIntoView: true }); } else if (!event.changes) { return null; } else { let rest = branch.length == 1 ? none : branch.slice(0, branch.length - 1); if (event.mapped) rest = addMappingToBranch(rest, event.mapped); return state.update({ changes: event.changes, selection: event.startSelection, effects: event.effects, annotations: fromHistory.of({ side, rest }), filter: false, userEvent: side == 0 ? "undo" : "redo", scrollIntoView: true }); } } }; HistoryState.empty = new HistoryState(none, none); var historyKeymap = [ { key: "Mod-z", run: undo, preventDefault: true }, { key: "Mod-y", mac: "Mod-Shift-z", run: redo, preventDefault: true }, { linux: "Ctrl-Shift-z", run: redo, preventDefault: true }, { key: "Mod-u", run: undoSelection, preventDefault: true }, { key: "Alt-u", mac: "Mod-Shift-u", run: redoSelection, preventDefault: true } ]; function updateSel(sel, by) { return EditorSelection.create(sel.ranges.map(by), sel.mainIndex); } function setSel(state, selection) { return state.update({ selection, scrollIntoView: true, userEvent: "select" }); } function moveSel({ state, dispatch }, how) { let selection = updateSel(state.selection, how); if (selection.eq(state.selection)) return false; dispatch(setSel(state, selection)); return true; } function rangeEnd(range, forward) { return EditorSelection.cursor(forward ? range.to : range.from); } function cursorByChar(view, forward) { return moveSel(view, (range) => range.empty ? view.moveByChar(range, forward) : rangeEnd(range, forward)); } function ltrAtCursor(view) { return view.textDirectionAt(view.state.selection.main.head) == Direction.LTR; } var cursorCharLeft = (view) => cursorByChar(view, !ltrAtCursor(view)); var cursorCharRight = (view) => cursorByChar(view, ltrAtCursor(view)); var cursorCharForward = (view) => cursorByChar(view, true); var cursorCharBackward = (view) => cursorByChar(view, false); function cursorByGroup(view, forward) { return moveSel(view, (range) => range.empty ? view.moveByGroup(range, forward) : rangeEnd(range, forward)); } var cursorGroupLeft = (view) => cursorByGroup(view, !ltrAtCursor(view)); var cursorGroupRight = (view) => cursorByGroup(view, ltrAtCursor(view)); var cursorGroupForward = (view) => cursorByGroup(view, true); var cursorGroupBackward = (view) => cursorByGroup(view, false); function moveBySubword(view, range, forward) { let categorize = view.state.charCategorizer(range.from); return view.moveByChar(range, forward, (start) => { let cat = CharCategory.Space, pos = range.from; let done = false, sawUpper = false, sawLower = false; let step = (next) => { if (done) return false; pos += forward ? next.length : -next.length; let nextCat = categorize(next), ahead; if (nextCat == CharCategory.Word && next.charCodeAt(0) < 128 && /[\W_]/.test(next)) nextCat = -1; if (cat == CharCategory.Space) cat = nextCat; if (cat != nextCat) return false; if (cat == CharCategory.Word) { if (next.toLowerCase() == next) { if (!forward && sawUpper) return false; sawLower = true; } else if (sawLower) { if (forward) return false; done = true; } else { if (sawUpper && forward && categorize(ahead = view.state.sliceDoc(pos, pos + 1)) == CharCategory.Word && ahead.toLowerCase() == ahead) return false; sawUpper = true; } } return true; }; step(start); return step; }); } function cursorBySubword(view, forward) { return moveSel(view, (range) => range.empty ? moveBySubword(view, range, forward) : rangeEnd(range, forward)); } var cursorSubwordForward = (view) => cursorBySubword(view, true); var cursorSubwordBackward = (view) => cursorBySubword(view, false); function interestingNode(state, node, bracketProp) { if (node.type.prop(bracketProp)) return true; let len = node.to - node.from; return len && (len > 2 || /[^\s,.;:]/.test(state.sliceDoc(node.from, node.to))) || node.firstChild; } function moveBySyntax(state, start, forward) { let pos = syntaxTree(state).resolveInner(start.head); let bracketProp = forward ? NodeProp.closedBy : NodeProp.openedBy; for (let at = start.head; ; ) { let next = forward ? pos.childAfter(at) : pos.childBefore(at); if (!next) break; if (interestingNode(state, next, bracketProp)) pos = next; else at = forward ? next.to : next.from; } let bracket = pos.type.prop(bracketProp), match, newPos; if (bracket && (match = forward ? matchBrackets(state, pos.from, 1) : matchBrackets(state, pos.to, -1)) && match.matched) newPos = forward ? match.end.to : match.end.from; else newPos = forward ? pos.to : pos.from; return EditorSelection.cursor(newPos, forward ? -1 : 1); } var cursorSyntaxLeft = (view) => moveSel(view, (range) => moveBySyntax(view.state, range, !ltrAtCursor(view))); var cursorSyntaxRight = (view) => moveSel(view, (range) => moveBySyntax(view.state, range, ltrAtCursor(view))); function cursorByLine(view, forward) { return moveSel(view, (range) => { if (!range.empty) return rangeEnd(range, forward); let moved = view.moveVertically(range, forward); return moved.head != range.head ? moved : view.moveToLineBoundary(range, forward); }); } var cursorLineUp = (view) => cursorByLine(view, false); var cursorLineDown = (view) => cursorByLine(view, true); function pageInfo(view) { let selfScroll = view.scrollDOM.clientHeight < view.scrollDOM.scrollHeight - 2; let marginTop = 0, marginBottom = 0, height; if (selfScroll) { for (let source of view.state.facet(EditorView.scrollMargins)) { let margins = source(view); if (margins === null || margins === void 0 ? void 0 : margins.top) marginTop = Math.max(margins === null || margins === void 0 ? void 0 : margins.top, marginTop); if (margins === null || margins === void 0 ? void 0 : margins.bottom) marginBottom = Math.max(margins === null || margins === void 0 ? void 0 : margins.bottom, marginBottom); } height = view.scrollDOM.clientHeight - marginTop - marginBottom; } else { height = (view.dom.ownerDocument.defaultView || window).innerHeight; } return { marginTop, marginBottom, selfScroll, height: Math.max(view.defaultLineHeight, height - 5) }; } function cursorByPage(view, forward) { let page = pageInfo(view); let { state } = view, selection = updateSel(state.selection, (range) => { return range.empty ? view.moveVertically(range, forward, page.height) : rangeEnd(range, forward); }); if (selection.eq(state.selection)) return false; let effect; if (page.selfScroll) { let startPos = view.coordsAtPos(state.selection.main.head); let scrollRect = view.scrollDOM.getBoundingClientRect(); let scrollTop = scrollRect.top + page.marginTop, scrollBottom = scrollRect.bottom - page.marginBottom; if (startPos && startPos.top > scrollTop && startPos.bottom < scrollBottom) effect = EditorView.scrollIntoView(selection.main.head, { y: "start", yMargin: startPos.top - scrollTop }); } view.dispatch(setSel(state, selection), { effects: effect }); return true; } var cursorPageUp = (view) => cursorByPage(view, false); var cursorPageDown = (view) => cursorByPage(view, true); function moveByLineBoundary(view, start, forward) { let line = view.lineBlockAt(start.head), moved = view.moveToLineBoundary(start, forward); if (moved.head == start.head && moved.head != (forward ? line.to : line.from)) moved = view.moveToLineBoundary(start, forward, false); if (!forward && moved.head == line.from && line.length) { let space = /^\s*/.exec(view.state.sliceDoc(line.from, Math.min(line.from + 100, line.to)))[0].length; if (space && start.head != line.from + space) moved = EditorSelection.cursor(line.from + space); } return moved; } var cursorLineBoundaryForward = (view) => moveSel(view, (range) => moveByLineBoundary(view, range, true)); var cursorLineBoundaryBackward = (view) => moveSel(view, (range) => moveByLineBoundary(view, range, false)); var cursorLineBoundaryLeft = (view) => moveSel(view, (range) => moveByLineBoundary(view, range, !ltrAtCursor(view))); var cursorLineBoundaryRight = (view) => moveSel(view, (range) => moveByLineBoundary(view, range, ltrAtCursor(view))); var cursorLineStart = (view) => moveSel(view, (range) => EditorSelection.cursor(view.lineBlockAt(range.head).from, 1)); var cursorLineEnd = (view) => moveSel(view, (range) => EditorSelection.cursor(view.lineBlockAt(range.head).to, -1)); function toMatchingBracket(state, dispatch, extend) { let found = false, selection = updateSel(state.selection, (range) => { let matching = matchBrackets(state, range.head, -1) || matchBrackets(state, range.head, 1) || range.head > 0 && matchBrackets(state, range.head - 1, 1) || range.head < state.doc.length && matchBrackets(state, range.head + 1, -1); if (!matching || !matching.end) return range; found = true; let head = matching.start.from == range.head ? matching.end.to : matching.end.from; return extend ? EditorSelection.range(range.anchor, head) : EditorSelection.cursor(head); }); if (!found) return false; dispatch(setSel(state, selection)); return true; } var cursorMatchingBracket = ({ state, dispatch }) => toMatchingBracket(state, dispatch, false); var selectMatchingBracket = ({ state, dispatch }) => toMatchingBracket(state, dispatch, true); function extendSel(view, how) { let selection = updateSel(view.state.selection, (range) => { let head = how(range); return EditorSelection.range(range.anchor, head.head, head.goalColumn, head.bidiLevel || void 0); }); if (selection.eq(view.state.selection)) return false; view.dispatch(setSel(view.state, selection)); return true; } function selectByChar(view, forward) { return extendSel(view, (range) => view.moveByChar(range, forward)); } var selectCharLeft = (view) => selectByChar(view, !ltrAtCursor(view)); var selectCharRight = (view) => selectByChar(view, ltrAtCursor(view)); var selectCharForward = (view) => selectByChar(view, true); var selectCharBackward = (view) => selectByChar(view, false); function selectByGroup(view, forward) { return extendSel(view, (range) => view.moveByGroup(range, forward)); } var selectGroupLeft = (view) => selectByGroup(view, !ltrAtCursor(view)); var selectGroupRight = (view) => selectByGroup(view, ltrAtCursor(view)); var selectGroupForward = (view) => selectByGroup(view, true); var selectGroupBackward = (view) => selectByGroup(view, false); function selectBySubword(view, forward) { return extendSel(view, (range) => moveBySubword(view, range, forward)); } var selectSubwordForward = (view) => selectBySubword(view, true); var selectSubwordBackward = (view) => selectBySubword(view, false); var selectSyntaxLeft = (view) => extendSel(view, (range) => moveBySyntax(view.state, range, !ltrAtCursor(view))); var selectSyntaxRight = (view) => extendSel(view, (range) => moveBySyntax(view.state, range, ltrAtCursor(view))); function selectByLine(view, forward) { return extendSel(view, (range) => view.moveVertically(range, forward)); } var selectLineUp = (view) => selectByLine(view, false); var selectLineDown = (view) => selectByLine(view, true); function selectByPage(view, forward) { return extendSel(view, (range) => view.moveVertically(range, forward, pageInfo(view).height)); } var selectPageUp = (view) => selectByPage(view, false); var selectPageDown = (view) => selectByPage(view, true); var selectLineBoundaryForward = (view) => extendSel(view, (range) => moveByLineBoundary(view, range, true)); var selectLineBoundaryBackward = (view) => extendSel(view, (range) => moveByLineBoundary(view, range, false)); var selectLineBoundaryLeft = (view) => extendSel(view, (range) => moveByLineBoundary(view, range, !ltrAtCursor(view))); var selectLineBoundaryRight = (view) => extendSel(view, (range) => moveByLineBoundary(view, range, ltrAtCursor(view))); var selectLineStart = (view) => extendSel(view, (range) => EditorSelection.cursor(view.lineBlockAt(range.head).from)); var selectLineEnd = (view) => extendSel(view, (range) => EditorSelection.cursor(view.lineBlockAt(range.head).to)); var cursorDocStart = ({ state, dispatch }) => { dispatch(setSel(state, { anchor: 0 })); return true; }; var cursorDocEnd = ({ state, dispatch }) => { dispatch(setSel(state, { anchor: state.doc.length })); return true; }; var selectDocStart = ({ state, dispatch }) => { dispatch(setSel(state, { anchor: state.selection.main.anchor, head: 0 })); return true; }; var selectDocEnd = ({ state, dispatch }) => { dispatch(setSel(state, { anchor: state.selection.main.anchor, head: state.doc.length })); return true; }; var selectAll = ({ state, dispatch }) => { dispatch(state.update({ selection: { anchor: 0, head: state.doc.length }, userEvent: "select" })); return true; }; var selectLine = ({ state, dispatch }) => { let ranges = selectedLineBlocks(state).map(({ from, to }) => EditorSelection.range(from, Math.min(to + 1, state.doc.length))); dispatch(state.update({ selection: EditorSelection.create(ranges), userEvent: "select" })); return true; }; var selectParentSyntax = ({ state, dispatch }) => { let selection = updateSel(state.selection, (range) => { var _a; let context = syntaxTree(state).resolveInner(range.head, 1); while (!(context.from < range.from && context.to >= range.to || context.to > range.to && context.from <= range.from || !((_a = context.parent) === null || _a === void 0 ? void 0 : _a.parent))) context = context.parent; return EditorSelection.range(context.to, context.from); }); dispatch(setSel(state, selection)); return true; }; var simplifySelection = ({ state, dispatch }) => { let cur = state.selection, selection = null; if (cur.ranges.length > 1) selection = EditorSelection.create([cur.main]); else if (!cur.main.empty) selection = EditorSelection.create([EditorSelection.cursor(cur.main.head)]); if (!selection) return false; dispatch(setSel(state, selection)); return true; }; function deleteBy(target, by) { if (target.state.readOnly) return false; let event = "delete.selection", { state } = target; let changes = state.changeByRange((range) => { let { from, to } = range; if (from == to) { let towards = by(from); if (towards < from) { event = "delete.backward"; towards = skipAtomic(target, towards, false); } else if (towards > from) { event = "delete.forward"; towards = skipAtomic(target, towards, true); } from = Math.min(from, towards); to = Math.max(to, towards); } else { from = skipAtomic(target, from, false); to = skipAtomic(target, to, true); } return from == to ? { range } : { changes: { from, to }, range: EditorSelection.cursor(from) }; }); if (changes.changes.empty) return false; target.dispatch(state.update(changes, { scrollIntoView: true, userEvent: event, effects: event == "delete.selection" ? EditorView.announce.of(state.phrase("Selection deleted")) : void 0 })); return true; } function skipAtomic(target, pos, forward) { if (target instanceof EditorView) for (let ranges of target.state.facet(EditorView.atomicRanges).map((f) => f(target))) ranges.between(pos, pos, (from, to) => { if (from < pos && to > pos) pos = forward ? to : from; }); return pos; } var deleteByChar = (target, forward) => deleteBy(target, (pos) => { let { state } = target, line = state.doc.lineAt(pos), before, targetPos; if (!forward && pos > line.from && pos < line.from + 200 && !/[^ \t]/.test(before = line.text.slice(0, pos - line.from))) { if (before[before.length - 1] == " ") return pos - 1; let col = countColumn(before, state.tabSize), drop = col % getIndentUnit(state) || getIndentUnit(state); for (let i = 0; i < drop && before[before.length - 1 - i] == " "; i++) pos--; targetPos = pos; } else { targetPos = findClusterBreak(line.text, pos - line.from, forward, forward) + line.from; if (targetPos == pos && line.number != (forward ? state.doc.lines : 1)) targetPos += forward ? 1 : -1; } return targetPos; }); var deleteCharBackward = (view) => deleteByChar(view, false); var deleteCharForward = (view) => deleteByChar(view, true); var deleteByGroup = (target, forward) => deleteBy(target, (start) => { let pos = start, { state } = target, line = state.doc.lineAt(pos); let categorize = state.charCategorizer(pos); for (let cat = null; ; ) { if (pos == (forward ? line.to : line.from)) { if (pos == start && line.number != (forward ? state.doc.lines : 1)) pos += forward ? 1 : -1; break; } let next = findClusterBreak(line.text, pos - line.from, forward) + line.from; let nextChar = line.text.slice(Math.min(pos, next) - line.from, Math.max(pos, next) - line.from); let nextCat = categorize(nextChar); if (cat != null && nextCat != cat) break; if (nextChar != " " || pos != start) cat = nextCat; pos = next; } return pos; }); var deleteGroupBackward = (target) => deleteByGroup(target, false); var deleteGroupForward = (target) => deleteByGroup(target, true); var deleteToLineEnd = (view) => deleteBy(view, (pos) => { let lineEnd = view.lineBlockAt(pos).to; return pos < lineEnd ? lineEnd : Math.min(view.state.doc.length, pos + 1); }); var deleteToLineStart = (view) => deleteBy(view, (pos) => { let lineStart = view.lineBlockAt(pos).from; return pos > lineStart ? lineStart : Math.max(0, pos - 1); }); var deleteTrailingWhitespace = ({ state, dispatch }) => { if (state.readOnly) return false; let changes = []; for (let pos = 0, prev = "", iter = state.doc.iter(); ; ) { iter.next(); if (iter.lineBreak || iter.done) { let trailing = prev.search(/\s+$/); if (trailing > -1) changes.push({ from: pos - (prev.length - trailing), to: pos }); if (iter.done) break; prev = ""; } else { prev = iter.value; } pos += iter.value.length; } if (!changes.length) return false; dispatch(state.update({ changes, userEvent: "delete" })); return true; }; var splitLine = ({ state, dispatch }) => { if (state.readOnly) return false; let changes = state.changeByRange((range) => { return { changes: { from: range.from, to: range.to, insert: Text.of(["", ""]) }, range: EditorSelection.cursor(range.from) }; }); dispatch(state.update(changes, { scrollIntoView: true, userEvent: "input" })); return true; }; var transposeChars = ({ state, dispatch }) => { if (state.readOnly) return false; let changes = state.changeByRange((range) => { if (!range.empty || range.from == 0 || range.from == state.doc.length) return { range }; let pos = range.from, line = state.doc.lineAt(pos); let from = pos == line.from ? pos - 1 : findClusterBreak(line.text, pos - line.from, false) + line.from; let to = pos == line.to ? pos + 1 : findClusterBreak(line.text, pos - line.from, true) + line.from; return { changes: { from, to, insert: state.doc.slice(pos, to).append(state.doc.slice(from, pos)) }, range: EditorSelection.cursor(to) }; }); if (changes.changes.empty) return false; dispatch(state.update(changes, { scrollIntoView: true, userEvent: "move.character" })); return true; }; function selectedLineBlocks(state) { let blocks = [], upto = -1; for (let range of state.selection.ranges) { let startLine = state.doc.lineAt(range.from), endLine = state.doc.lineAt(range.to); if (!range.empty && range.to == endLine.from) endLine = state.doc.lineAt(range.to - 1); if (upto >= startLine.number) { let prev = blocks[blocks.length - 1]; prev.to = endLine.to; prev.ranges.push(range); } else { blocks.push({ from: startLine.from, to: endLine.to, ranges: [range] }); } upto = endLine.number + 1; } return blocks; } function moveLine(state, dispatch, forward) { if (state.readOnly) return false; let changes = [], ranges = []; for (let block of selectedLineBlocks(state)) { if (forward ? block.to == state.doc.length : block.from == 0) continue; let nextLine = state.doc.lineAt(forward ? block.to + 1 : block.from - 1); let size = nextLine.length + 1; if (forward) { changes.push({ from: block.to, to: nextLine.to }, { from: block.from, insert: nextLine.text + state.lineBreak }); for (let r of block.ranges) ranges.push(EditorSelection.range(Math.min(state.doc.length, r.anchor + size), Math.min(state.doc.length, r.head + size))); } else { changes.push({ from: nextLine.from, to: block.from }, { from: block.to, insert: state.lineBreak + nextLine.text }); for (let r of block.ranges) ranges.push(EditorSelection.range(r.anchor - size, r.head - size)); } } if (!changes.length) return false; dispatch(state.update({ changes, scrollIntoView: true, selection: EditorSelection.create(ranges, state.selection.mainIndex), userEvent: "move.line" })); return true; } var moveLineUp = ({ state, dispatch }) => moveLine(state, dispatch, false); var moveLineDown = ({ state, dispatch }) => moveLine(state, dispatch, true); function copyLine(state, dispatch, forward) { if (state.readOnly) return false; let changes = []; for (let block of selectedLineBlocks(state)) { if (forward) changes.push({ from: block.from, insert: state.doc.slice(block.from, block.to) + state.lineBreak }); else changes.push({ from: block.to, insert: state.lineBreak + state.doc.slice(block.from, block.to) }); } dispatch(state.update({ changes, scrollIntoView: true, userEvent: "input.copyline" })); return true; } var copyLineUp = ({ state, dispatch }) => copyLine(state, dispatch, false); var copyLineDown = ({ state, dispatch }) => copyLine(state, dispatch, true); var deleteLine = (view) => { if (view.state.readOnly) return false; let { state } = view, changes = state.changes(selectedLineBlocks(state).map(({ from, to }) => { if (from > 0) from--; else if (to < state.doc.length) to++; return { from, to }; })); let selection = updateSel(state.selection, (range) => view.moveVertically(range, true)).map(changes); view.dispatch({ changes, selection, scrollIntoView: true, userEvent: "delete.line" }); return true; }; var insertNewline = ({ state, dispatch }) => { dispatch(state.update(state.replaceSelection(state.lineBreak), { scrollIntoView: true, userEvent: "input" })); return true; }; function isBetweenBrackets(state, pos) { if (/\(\)|\[\]|\{\}/.test(state.sliceDoc(pos - 1, pos + 1))) return { from: pos, to: pos }; let context = syntaxTree(state).resolveInner(pos); let before = context.childBefore(pos), after = context.childAfter(pos), closedBy; if (before && after && before.to <= pos && after.from >= pos && (closedBy = before.type.prop(NodeProp.closedBy)) && closedBy.indexOf(after.name) > -1 && state.doc.lineAt(before.to).from == state.doc.lineAt(after.from).from) return { from: before.to, to: after.from }; return null; } var insertNewlineAndIndent = newlineAndIndent(false); var insertBlankLine = newlineAndIndent(true); function newlineAndIndent(atEof) { return ({ state, dispatch }) => { if (state.readOnly) return false; let changes = state.changeByRange((range) => { let { from, to } = range, line = state.doc.lineAt(from); let explode = !atEof && from == to && isBetweenBrackets(state, from); if (atEof) from = to = (to <= line.to ? line : state.doc.lineAt(to)).to; let cx = new IndentContext(state, { simulateBreak: from, simulateDoubleBreak: !!explode }); let indent = getIndentation(cx, from); if (indent == null) indent = /^\s*/.exec(state.doc.lineAt(from).text)[0].length; while (to < line.to && /\s/.test(line.text[to - line.from])) to++; if (explode) ({ from, to } = explode); else if (from > line.from && from < line.from + 100 && !/\S/.test(line.text.slice(0, from))) from = line.from; let insert = ["", indentString(state, indent)]; if (explode) insert.push(indentString(state, cx.lineIndent(line.from, -1))); return { changes: { from, to, insert: Text.of(insert) }, range: EditorSelection.cursor(from + 1 + insert[1].length) }; }); dispatch(state.update(changes, { scrollIntoView: true, userEvent: "input" })); return true; }; } function changeBySelectedLine(state, f) { let atLine = -1; return state.changeByRange((range) => { let changes = []; for (let pos = range.from; pos <= range.to; ) { let line = state.doc.lineAt(pos); if (line.number > atLine && (range.empty || range.to > line.from)) { f(line, changes, range); atLine = line.number; } pos = line.to + 1; } let changeSet = state.changes(changes); return { changes, range: EditorSelection.range(changeSet.mapPos(range.anchor, 1), changeSet.mapPos(range.head, 1)) }; }); } var indentSelection = ({ state, dispatch }) => { if (state.readOnly) return false; let updated = /* @__PURE__ */ Object.create(null); let context = new IndentContext(state, { overrideIndentation: (start) => { let found = updated[start]; return found == null ? -1 : found; } }); let changes = changeBySelectedLine(state, (line, changes2, range) => { let indent = getIndentation(context, line.from); if (indent == null) return; if (!/\S/.test(line.text)) indent = 0; let cur = /^\s*/.exec(line.text)[0]; let norm = indentString(state, indent); if (cur != norm || range.from < line.from + cur.length) { updated[line.from] = indent; changes2.push({ from: line.from, to: line.from + cur.length, insert: norm }); } }); if (!changes.changes.empty) dispatch(state.update(changes, { userEvent: "indent" })); return true; }; var indentMore = ({ state, dispatch }) => { if (state.readOnly) return false; dispatch(state.update(changeBySelectedLine(state, (line, changes) => { changes.push({ from: line.from, insert: state.facet(indentUnit) }); }), { userEvent: "input.indent" })); return true; }; var indentLess = ({ state, dispatch }) => { if (state.readOnly) return false; dispatch(state.update(changeBySelectedLine(state, (line, changes) => { let space = /^\s*/.exec(line.text)[0]; if (!space) return; let col = countColumn(space, state.tabSize), keep = 0; let insert = indentString(state, Math.max(0, col - getIndentUnit(state))); while (keep < space.length && keep < insert.length && space.charCodeAt(keep) == insert.charCodeAt(keep)) keep++; changes.push({ from: line.from + keep, to: line.from + space.length, insert: insert.slice(keep) }); }), { userEvent: "delete.dedent" })); return true; }; var insertTab = ({ state, dispatch }) => { if (state.selection.ranges.some((r) => !r.empty)) return indentMore({ state, dispatch }); dispatch(state.update(state.replaceSelection(" "), { scrollIntoView: true, userEvent: "input" })); return true; }; var emacsStyleKeymap = [ { key: "Ctrl-b", run: cursorCharLeft, shift: selectCharLeft, preventDefault: true }, { key: "Ctrl-f", run: cursorCharRight, shift: selectCharRight }, { key: "Ctrl-p", run: cursorLineUp, shift: selectLineUp }, { key: "Ctrl-n", run: cursorLineDown, shift: selectLineDown }, { key: "Ctrl-a", run: cursorLineStart, shift: selectLineStart }, { key: "Ctrl-e", run: cursorLineEnd, shift: selectLineEnd }, { key: "Ctrl-d", run: deleteCharForward }, { key: "Ctrl-h", run: deleteCharBackward }, { key: "Ctrl-k", run: deleteToLineEnd }, { key: "Ctrl-Alt-h", run: deleteGroupBackward }, { key: "Ctrl-o", run: splitLine }, { key: "Ctrl-t", run: transposeChars }, { key: "Ctrl-v", run: cursorPageDown } ]; var standardKeymap = [ { key: "ArrowLeft", run: cursorCharLeft, shift: selectCharLeft, preventDefault: true }, { key: "Mod-ArrowLeft", mac: "Alt-ArrowLeft", run: cursorGroupLeft, shift: selectGroupLeft, preventDefault: true }, { mac: "Cmd-ArrowLeft", run: cursorLineBoundaryLeft, shift: selectLineBoundaryLeft, preventDefault: true }, { key: "ArrowRight", run: cursorCharRight, shift: selectCharRight, preventDefault: true }, { key: "Mod-ArrowRight", mac: "Alt-ArrowRight", run: cursorGroupRight, shift: selectGroupRight, preventDefault: true }, { mac: "Cmd-ArrowRight", run: cursorLineBoundaryRight, shift: selectLineBoundaryRight, preventDefault: true }, { key: "ArrowUp", run: cursorLineUp, shift: selectLineUp, preventDefault: true }, { mac: "Cmd-ArrowUp", run: cursorDocStart, shift: selectDocStart }, { mac: "Ctrl-ArrowUp", run: cursorPageUp, shift: selectPageUp }, { key: "ArrowDown", run: cursorLineDown, shift: selectLineDown, preventDefault: true }, { mac: "Cmd-ArrowDown", run: cursorDocEnd, shift: selectDocEnd }, { mac: "Ctrl-ArrowDown", run: cursorPageDown, shift: selectPageDown }, { key: "PageUp", run: cursorPageUp, shift: selectPageUp }, { key: "PageDown", run: cursorPageDown, shift: selectPageDown }, { key: "Home", run: cursorLineBoundaryBackward, shift: selectLineBoundaryBackward, preventDefault: true }, { key: "Mod-Home", run: cursorDocStart, shift: selectDocStart }, { key: "End", run: cursorLineBoundaryForward, shift: selectLineBoundaryForward, preventDefault: true }, { key: "Mod-End", run: cursorDocEnd, shift: selectDocEnd }, { key: "Enter", run: insertNewlineAndIndent }, { key: "Mod-a", run: selectAll }, { key: "Backspace", run: deleteCharBackward, shift: deleteCharBackward }, { key: "Delete", run: deleteCharForward }, { key: "Mod-Backspace", mac: "Alt-Backspace", run: deleteGroupBackward }, { key: "Mod-Delete", mac: "Alt-Delete", run: deleteGroupForward }, { mac: "Mod-Backspace", run: deleteToLineStart }, { mac: "Mod-Delete", run: deleteToLineEnd } ].concat(emacsStyleKeymap.map((b) => ({ mac: b.key, run: b.run, shift: b.shift }))); var defaultKeymap = [ { key: "Alt-ArrowLeft", mac: "Ctrl-ArrowLeft", run: cursorSyntaxLeft, shift: selectSyntaxLeft }, { key: "Alt-ArrowRight", mac: "Ctrl-ArrowRight", run: cursorSyntaxRight, shift: selectSyntaxRight }, { key: "Alt-ArrowUp", run: moveLineUp }, { key: "Shift-Alt-ArrowUp", run: copyLineUp }, { key: "Alt-ArrowDown", run: moveLineDown }, { key: "Shift-Alt-ArrowDown", run: copyLineDown }, { key: "Escape", run: simplifySelection }, { key: "Mod-Enter", run: insertBlankLine }, { key: "Alt-l", mac: "Ctrl-l", run: selectLine }, { key: "Mod-i", run: selectParentSyntax, preventDefault: true }, { key: "Mod-[", run: indentLess }, { key: "Mod-]", run: indentMore }, { key: "Mod-Alt-\\", run: indentSelection }, { key: "Shift-Mod-k", run: deleteLine }, { key: "Shift-Mod-\\", run: cursorMatchingBracket }, { key: "Mod-/", run: toggleComment }, { key: "Alt-A", run: toggleBlockComment } ].concat(standardKeymap); var indentWithTab = { key: "Tab", run: indentMore, shift: indentLess }; export { toggleComment, toggleLineComment, lineComment, lineUncomment, toggleBlockComment, blockComment, blockUncomment, toggleBlockCommentByLine, isolateHistory, invertedEffects, history, historyField, undo, redo, undoSelection, redoSelection, undoDepth, redoDepth, historyKeymap, cursorCharLeft, cursorCharRight, cursorCharForward, cursorCharBackward, cursorGroupLeft, cursorGroupRight, cursorGroupForward, cursorGroupBackward, cursorSubwordForward, cursorSubwordBackward, cursorSyntaxLeft, cursorSyntaxRight, cursorLineUp, cursorLineDown, cursorPageUp, cursorPageDown, cursorLineBoundaryForward, cursorLineBoundaryBackward, cursorLineBoundaryLeft, cursorLineBoundaryRight, cursorLineStart, cursorLineEnd, cursorMatchingBracket, selectMatchingBracket, selectCharLeft, selectCharRight, selectCharForward, selectCharBackward, selectGroupLeft, selectGroupRight, selectGroupForward, selectGroupBackward, selectSubwordForward, selectSubwordBackward, selectSyntaxLeft, selectSyntaxRight, selectLineUp, selectLineDown, selectPageUp, selectPageDown, selectLineBoundaryForward, selectLineBoundaryBackward, selectLineBoundaryLeft, selectLineBoundaryRight, selectLineStart, selectLineEnd, cursorDocStart, cursorDocEnd, selectDocStart, selectDocEnd, selectAll, selectLine, selectParentSyntax, simplifySelection, deleteCharBackward, deleteCharForward, deleteGroupBackward, deleteGroupForward, deleteToLineEnd, deleteToLineStart, deleteTrailingWhitespace, splitLine, transposeChars, moveLineUp, moveLineDown, copyLineUp, copyLineDown, deleteLine, insertNewline, insertNewlineAndIndent, insertBlankLine, indentSelection, indentMore, indentLess, insertTab, emacsStyleKeymap, standardKeymap, defaultKeymap, indentWithTab }; //# sourceMappingURL=chunk-TRAAS4SM.js.map