braces.ts 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. const BRACES = {
  2. '[': ']',
  3. '{': '}',
  4. '(': ')',
  5. };
  6. const NON_SELECTOR_SPACE_REGEXP = / (?![^}]+})/;
  7. export default function BracesPlugin() {
  8. return {
  9. onKeyDown(event, change) {
  10. const { value } = change;
  11. if (!value.isCollapsed) {
  12. return undefined;
  13. }
  14. switch (event.key) {
  15. case '{':
  16. case '[': {
  17. event.preventDefault();
  18. // Insert matching braces
  19. change
  20. .insertText(`${event.key}${BRACES[event.key]}`)
  21. .move(-1)
  22. .focus();
  23. return true;
  24. }
  25. case '(': {
  26. event.preventDefault();
  27. const text = value.anchorText.text;
  28. const offset = value.anchorOffset;
  29. const delimiterIndex = text.slice(offset).search(NON_SELECTOR_SPACE_REGEXP);
  30. const length = delimiterIndex > -1 ? delimiterIndex + offset : text.length;
  31. const forward = length - offset;
  32. // Insert matching braces
  33. change
  34. .insertText(event.key)
  35. .move(forward)
  36. .insertText(BRACES[event.key])
  37. .move(-1 - forward)
  38. .focus();
  39. return true;
  40. }
  41. default: {
  42. break;
  43. }
  44. }
  45. return undefined;
  46. },
  47. };
  48. }