1
0

highlight.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package highlight
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. sitter "github.com/tree-sitter/go-tree-sitter/bindings/go"
  8. )
  9. type HighlightEngine struct {
  10. parser *sitter.Parser
  11. wasmDir string
  12. languages map[string]*sitter.Language
  13. }
  14. func NewHighlightEngine() (*HighlightEngine, error) {
  15. home, err := os.UserHomeDir()
  16. if err != nil {
  17. return nil, err
  18. }
  19. wasmDir := filepath.Join(home, ".config", "moose", "tree-sitter")
  20. return &HighlightEngine{
  21. parser: sitter.NewParser(),
  22. wasmDir: wasmDir,
  23. languages: make(map[string]*sitter.Language),
  24. }, nil
  25. }
  26. func (h *HighlightEngine) LoadLanguage(ctx context.Context, langName string) (*sitter.Language, error) {
  27. if lang, exists := h.languages[langName]; exists {
  28. return lang, nil
  29. }
  30. wasmFile := fmt.Sprintf("tree-sitter-%s.wasm", langName)
  31. wasmPath := filepath.Join(h.wasmDir, wasmFile)
  32. wasmBytes, err := os.ReadFile(wasmPath)
  33. if err != nil {
  34. return nil, fmt.Errorf("failed to read grammar %s: %w", wasmPath, err)
  35. }
  36. lang, err := sitter.NewWasmLanguage(ctx, wasmBytes, fmt.Sprintf("tree_sitter_%s", langName))
  37. if err != nil {
  38. return nil, fmt.Errorf("failed to load WASM language %s: %w", langName, err)
  39. }
  40. h.languages[langName] = lang
  41. return lang, nil
  42. }
  43. func (h *HighlightEngine) ParseBuffer(ctx context.Context, langName string, content []byte) (*sitter.Tree, error) {
  44. lang, err := h.LoadLanguage(ctx, langName)
  45. if err != nil {
  46. return nil, err
  47. }
  48. h.parser.SetLanguage(lang)
  49. tree := h.parser.Parse(content, nil)
  50. return tree, nil
  51. }