Johan Rong 3 days ago
parent
commit
d9c1ce8593
5 changed files with 88 additions and 3 deletions
  1. 4 0
      go.mod
  2. 8 0
      go.sum
  3. 7 3
      internal/extension/extension.go
  4. 64 0
      internal/extension/highlight/highlight.go
  5. 5 0
      internal/extension/treesitter.go

+ 4 - 0
go.mod

@@ -6,6 +6,7 @@ require (
 	github.com/creasty/defaults v1.8.0
 	github.com/davecgh/go-spew v1.1.1
 	github.com/gdamore/tcell/v3 v3.4.2
+	github.com/malivvan/tree-sitter v0.0.1
 	github.com/yuin/gopher-lua v1.1.2
 	github.com/zyedidia/rope v0.0.0-20210616205215-37fbf22eab3a
 	golang.design/x/clipboard v0.9.0
@@ -17,6 +18,9 @@ require (
 	github.com/ebitengine/purego v0.10.2 // indirect
 	github.com/gdamore/encoding v1.0.1 // indirect
 	github.com/lucasb-eyer/go-colorful v1.4.1 // indirect
+	github.com/mattn/go-pointer v0.0.1 // indirect
+	github.com/tetratelabs/wazero v1.8.2 // indirect
+	github.com/tree-sitter/go-tree-sitter v0.25.0 // indirect
 	golang.design/x/x11 v0.2.0 // indirect
 	golang.org/x/exp/shiny v0.0.0-20260820142414-ca536658362e // indirect
 	golang.org/x/image v0.45.0 // indirect

+ 8 - 0
go.sum

@@ -14,6 +14,14 @@ github.com/gdamore/tcell/v3 v3.4.2 h1:gGW+6z2Bz5Wl2mNwFlm9+eRmg2JQrWcKjSkL1LRfpN
 github.com/gdamore/tcell/v3 v3.4.2/go.mod h1:Oe5U3S3jm3NzypswDNUhe+LUnF5CoFq2b4sepD++QHo=
 github.com/lucasb-eyer/go-colorful v1.4.1 h1:1EO+WB73+EH8EVbzlrG3KLAfEypQWVHIBqlTf+2hNss=
 github.com/lucasb-eyer/go-colorful v1.4.1/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/malivvan/tree-sitter v0.0.1 h1:dlU+RIMzizvWygTQ6gCRKeNMrUhV7rw+uxgozE+kw1M=
+github.com/malivvan/tree-sitter v0.0.1/go.mod h1:8P6n6OqHoda94dibHUVYMGEh7cq7z/V3QhNMqdXiW5E=
+github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
+github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
+github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4=
+github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
+github.com/tree-sitter/go-tree-sitter v0.25.0 h1:sx6kcg8raRFCvc9BnXglke6axya12krCJF5xJ2sftRU=
+github.com/tree-sitter/go-tree-sitter v0.25.0/go.mod h1:r77ig7BikoZhHrrsjAnv8RqGti5rtSyvDHPzgTPsUuU=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yuin/gopher-lua v1.1.2 h1:yF/FjE3hD65tBbt0VXLE13HWS9h34fdzJmrWRXwobGA=
 github.com/yuin/gopher-lua v1.1.2/go.mod h1:7aRmXIWl37SqRf0koeyylBEzJ+aPt8A+mmkQ4f1ntR8=

+ 7 - 3
internal/extension/extension.go

@@ -3,17 +3,20 @@ package extension
 import (
 	"embed"
 	"fmt"
-	lua "github.com/yuin/gopher-lua"
 	"moose/internal/editor"
+	"moose/internal/extension/highlight"
 	"path/filepath"
 	"strings"
+
+	lua "github.com/yuin/gopher-lua"
 )
 
 type ExtensionManager struct {
 	L           *lua.LState
 	M           *editor.Model
+	HE			*highlight.HighlightEngine
 	LoadedFiles []string
-	
+
 	currentDiskDir  string
 	currentEmbedDir string
 }
@@ -25,9 +28,10 @@ func NewExtensionManager(m *editor.Model) *ExtensionManager {
 	em := &ExtensionManager{
 		L: lua.NewState(),
 		M: m,
+		HE: highlight.NewHighlightEngine(),
 	}
 
-	lua.OpenPackage(em.L) 
+	lua.OpenPackage(em.L)
 
 	em.registerAPI()
 	em.registerExtensionSearcher()

+ 64 - 0
internal/extension/highlight/highlight.go

@@ -0,0 +1,64 @@
+package highlight
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"path/filepath"
+
+	sitter "github.com/tree-sitter/go-tree-sitter/bindings/go"
+)
+
+type HighlightEngine struct {
+	parser    *sitter.Parser
+	wasmDir   string
+	languages map[string]*sitter.Language
+}
+
+func NewHighlightEngine() (*HighlightEngine, error) {
+	home, err := os.UserHomeDir()
+	if err != nil {
+		return nil, err
+	}
+
+	wasmDir := filepath.Join(home, ".config", "moose", "tree-sitter")
+
+	return &HighlightEngine{
+		parser:    sitter.NewParser(),
+		wasmDir:   wasmDir,
+		languages: make(map[string]*sitter.Language),
+	}, nil
+}
+
+func (h *HighlightEngine) LoadLanguage(ctx context.Context, langName string) (*sitter.Language, error) {
+	if lang, exists := h.languages[langName]; exists {
+		return lang, nil
+	}
+
+	wasmFile := fmt.Sprintf("tree-sitter-%s.wasm", langName)
+	wasmPath := filepath.Join(h.wasmDir, wasmFile)
+
+	wasmBytes, err := os.ReadFile(wasmPath)
+	if err != nil {
+		return nil, fmt.Errorf("failed to read grammar %s: %w", wasmPath, err)
+	}
+
+	lang, err := sitter.NewWasmLanguage(ctx, wasmBytes, fmt.Sprintf("tree_sitter_%s", langName))
+	if err != nil {
+		return nil, fmt.Errorf("failed to load WASM language %s: %w", langName, err)
+	}
+
+	h.languages[langName] = lang
+	return lang, nil
+}
+
+func (h *HighlightEngine) ParseBuffer(ctx context.Context, langName string, content []byte) (*sitter.Tree, error) {
+	lang, err := h.LoadLanguage(ctx, langName)
+	if err != nil {
+		return nil, err
+	}
+
+	h.parser.SetLanguage(lang)
+	tree := h.parser.Parse(content, nil)
+	return tree, nil
+}

+ 5 - 0
internal/extension/treesitter.go

@@ -0,0 +1,5 @@
+package extension
+
+import (
+
+)