Skip to content

Commit

Permalink
Fix bracket matching
Browse files Browse the repository at this point in the history
  • Loading branch information
fonsp committed Jan 17, 2025
1 parent e0b5b3f commit 364df4f
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions frontend/components/CellInput/block_matcher_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ function match_try_node(node) {
finally_node && { from: finally_node.from, to: finally_node.to },
{ from: possibly_end.from, to: possibly_end.to },
].filter((x) => x != null)

}

function match_block(node) {
Expand Down Expand Up @@ -207,11 +206,7 @@ function match_block(node) {
return decorations
}

if (node.name === "try"
|| node.name === "catch"
|| node.name === "finally"
|| node.name === "else") {

if (node.name === "try" || node.name === "catch" || node.name === "finally" || node.name === "else") {
if (node.name === "catch") node = node.parent
if (node.name === "finally") node = node.parent
if (node.name === "else") node = node.parent
Expand Down Expand Up @@ -299,26 +294,30 @@ export function matchBrackets(state, pos, dir, config = {}) {
node = tree.resolveInner(pos, dir)

let result = match_block(node)
return result || matchPlainBrackets(state, pos, dir, tree, node.type, maxScanDistance, brackets)
return result || matchPlainBrackets(state, pos, dir, tree, bracket_node_name_normalizer(node.name), maxScanDistance, brackets)
}

function matchPlainBrackets(state, pos, dir, tree, tokenType, maxScanDistance, brackets) {
console.log("trying to match", pos, dir, tokenType, maxScanDistance, brackets)
let startCh = dir < 0 ? state.sliceDoc(pos - 1, pos) : state.sliceDoc(pos, pos + 1)
let bracket = brackets.indexOf(startCh)
if (bracket < 0 || (bracket % 2 == 0) != dir > 0) return null
let startToken = { from: dir < 0 ? pos - 1 : pos, to: dir > 0 ? pos + 1 : pos }
let iter = state.doc.iterRange(pos, dir > 0 ? state.doc.length : 0),
depth = 0
for (let distance = 0; !iter.next().done && distance <= maxScanDistance; ) {
console.log("matching", distance, pos, dir, tokenType, maxScanDistance, brackets)
let text = iter.value
if (dir < 0) distance += text.length
let basePos = pos + distance * dir
for (let pos = dir > 0 ? 0 : text.length - 1, end = dir > 0 ? text.length : -1; pos != end; pos += dir) {
let found = brackets.indexOf(text[pos])
if (found < 0 || tree.resolve(basePos + pos, 1).type != tokenType) continue
if (found < 0 || bracket_node_name_normalizer(tree.resolve(basePos + pos, 1).name) != tokenType) continue
if ((found % 2 == 0) == dir > 0) {
depth++
} else if (depth == 1) {
// Closing
console.log("zomgg")
if (found >> 1 == bracket >> 1) {
return [startToken, { from: basePos + pos, to: basePos + pos + 1 }]
} else {
Expand All @@ -330,5 +329,25 @@ function matchPlainBrackets(state, pos, dir, tree, tokenType, maxScanDistance, b
}
if (dir > 0) distance += text.length
}
console.log(iter.done, startToken)
return iter.done ? [startToken] : null
}

/**
* Little modification to the original matchPlainBrackets function: in our Julia language, the node that opens a bracket is called "(". In e.g. markdown it's called LinkMark or something (the same name for opening and closing). We don't have this so we make them equal.
*/
const bracket_node_name_normalizer = (/** @type {String} */ node_name) => {
switch (node_name) {
case "(":
case ")":
return "()"
case "[":
case "]":
return "[]"
case "{":
case "}":
return "{}"
default:
return node_name
}
}

0 comments on commit 364df4f

Please sign in to comment.