completions.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { CompletionContext, CompletionSource } from '@codemirror/autocomplete'
  2. import { syntaxTree } from '@codemirror/language'
  3. import { EditorState } from '@codemirror/state'
  4. import { SyntaxNode } from '@lezer/common'
  5. import { ancestorOfNodeWithType } from './ancestors'
  6. export const ifInType = (
  7. type: string,
  8. source: CompletionSource
  9. ): CompletionSource => {
  10. return (context: CompletionContext) => {
  11. const tree = syntaxTree(context.state)
  12. let node: SyntaxNode | null = tree.resolveInner(context.pos, -1)
  13. while (node) {
  14. if (node.type.is(type)) {
  15. return source(context)
  16. }
  17. node = node.parent
  18. }
  19. return null
  20. }
  21. }
  22. export function isInEmptyArgumentNodeForAutocomplete(state: EditorState) {
  23. const main = state.selection.main
  24. if (!main.empty) {
  25. return false
  26. }
  27. const pos = main.anchor
  28. const tree = syntaxTree(state)
  29. if (tree.length < pos) {
  30. return false
  31. }
  32. const nodeLeft = tree.resolveInner(pos, -1)
  33. if (!nodeLeft.type.is('OpenBrace')) {
  34. return false
  35. }
  36. const nodeRight = tree.resolveInner(pos, 1)
  37. if (!nodeRight.type.is('CloseBrace')) {
  38. return false
  39. }
  40. const ancestor = ancestorOfNodeWithType(
  41. nodeLeft,
  42. 'EnvNameGroup',
  43. 'BibliographyStyleArgument',
  44. 'BibliographyArgument',
  45. 'BibKeyArgument',
  46. 'DocumentClassArgument',
  47. 'FilePathArgument',
  48. 'RefArgument',
  49. 'PackageArgument'
  50. )
  51. if (!ancestor) {
  52. return false
  53. }
  54. return ancestor.from === nodeLeft.from && ancestor.to === nodeRight.to
  55. }