common.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { ensureSyntaxTree } from '@codemirror/language'
  2. import { EditorState } from '@codemirror/state'
  3. import { SyntaxNode } from '@lezer/common'
  4. const HUNDRED_MS = 100
  5. export const previousSiblingIs = (
  6. state: EditorState,
  7. pos: number,
  8. expectedName: string
  9. ): boolean | null => {
  10. const tree = ensureSyntaxTree(state, pos, HUNDRED_MS)
  11. if (!tree) {
  12. return null
  13. }
  14. const thisNode = tree.resolve(pos)
  15. const previousNode = thisNode?.prevSibling
  16. return previousNode?.type.name === expectedName
  17. }
  18. export const getOptionalArgumentText = (
  19. state: EditorState,
  20. optionalArgumentNode: SyntaxNode
  21. ): string | undefined => {
  22. const shortArgNode = optionalArgumentNode.getChild('ShortOptionalArg')
  23. if (shortArgNode) {
  24. return state.doc.sliceString(shortArgNode.from, shortArgNode.to)
  25. }
  26. }
  27. export const nodeHasError = (node: SyntaxNode): boolean => {
  28. let hasError = false
  29. node.cursor().iterate(({ type }) => {
  30. if (hasError) return false
  31. if (type.isError) {
  32. hasError = true
  33. return false
  34. }
  35. return true
  36. })
  37. return hasError
  38. }
  39. export const childOfNodeWithType = (
  40. node: SyntaxNode,
  41. ...types: (string | number)[]
  42. ): SyntaxNode | null => {
  43. let childOfType: SyntaxNode | null = null
  44. node.cursor().iterate(child => {
  45. if (childOfType !== null) {
  46. return false
  47. }
  48. for (const type of types) {
  49. if (child.type.is(type)) {
  50. childOfType = child.node
  51. return false
  52. }
  53. }
  54. return true
  55. })
  56. return childOfType
  57. }