Close brackets extension modification (closingBrackets)

When closing brackets using closingBrackets extension, I would like to

  • If syntaxTree condition is met
    __ add some spaces in between the closing brackets
    __ else do nothing

Based on the docs, the way I think this should be approached is via transaction filter

EditorState.transactionFilter.of((tr) => {
    if (!tr.isUserEvent('closeBrakets') return tr;
    // Do my modification
    const modifiedTr = { ...tr };
    return modifiedTr;
  })

The problem I’ve found is that I don’t know a way to identify correctly if that transaction is coming from closeBrackets extension. Maybe adding an Annotations on the extension itself would allow me to identify it.

Also, I’m not sure if isUserEvent is the right way to do the filtering since it is not actually a user event.

Ok, I got it working.

  • How do I listen to the extension? Instead of Annotations I use the SideEffect closeBracketEffect from closingBrackets. Of course this is not exposed so I had to patch the dependency
  • How do I check the ast condition? I only needed to check previous character so I use the main selection to get it
  • How do I change/compose the transition changes? I use iterChanges and create a new set of changes. There might be a better way to do this.

I’d appreciate if someone could tell me if I’m breaking some good practices.

Here is the working code:

EditorState.transactionFilter.of((tr) => {
  const hasCloseBracketEffect = tr.effects.some((e) => {
    return e.is(closeBracketEffect);
  });
  if (!hasCloseBracketEffect) {
    return tr;
  }

  const currentAnchor = tr.startState.selection.main.head;
  const valueBeforeCursor = tr.startState.doc.slice(
    currentAnchor - 1,
    currentAnchor,
  );
  const hasBracketBefore = valueBeforeCursor.toString().includes('{');
  if (!hasBracketBefore) {
    return tr;
  }

  const bracketChangesWithSpaces: ChangeSpec[] = [];

  const anchor = currentAnchor + 2;
  tr.changes.iterChanges((from, to) => {

    bracketChangesWithSpaces.push({
      from,
      to,
      insert: '{  }',
    });
  });

  return {
    ...tr,
    changes: bracketChangesWithSpaces,
    selection: { anchor },
  };
})
1 Like

I think this might be easier to implement by registering a separate input handler that handles your situation, and registering that with a higher precedence than closing brackets, overriding it when appropriate.

1 Like