浏览代码

More base extension system stuff

Johan Rong 1 周之前
父节点
当前提交
2127061372
共有 3 个文件被更改,包括 85 次插入0 次删除
  1. 76 0
      internal/extension/extension.go
  2. 2 0
      internal/extension/lua/init.lua
  3. 7 0
      internal/extension/lua/test.lua

+ 76 - 0
internal/extension/extension.go

@@ -4,6 +4,9 @@ import (
 	"fmt"
 	lua "github.com/yuin/gopher-lua"
 	"moose/internal/editor"
+	"embed"
+	"path/filepath"
+	"strings"
 )
 
 type ExtensionManager struct {
@@ -12,6 +15,9 @@ type ExtensionManager struct {
 	LoadedFiles []string
 }
 
+//go:embed lua
+var embeddedScripts embed.FS
+
 func NewExtensionManager(m *editor.Model) *ExtensionManager {
 	em := &ExtensionManager{
 		L: lua.NewState(),
@@ -19,9 +25,59 @@ func NewExtensionManager(m *editor.Model) *ExtensionManager {
 	}
 
 	em.registerAPI()
+	em.registerEmbedSearcher()
+
+	if err := em.LoadEmbeddedFile("init.lua"); err != nil {
+		m.Mode = editor.ModeNormal
+		m.BM.PaletteBuffer.Clear()
+		m.BM.PaletteBuffer.Insert("moose.error:Lua error " + err.Error())
+	}
+
 	return em
 }
 
+func (em *ExtensionManager) registerEmbedSearcher() {
+	if em.L == nil {
+		return
+	}
+
+	pkg := em.L.GetGlobal("package")
+	if pkg.Type() == lua.LTNil {
+		return
+	}
+
+	loadersVal := em.L.GetField(pkg, "loaders")
+	packageLoaders, ok := loadersVal.(*lua.LTable)
+	if !ok {
+		return
+	}
+
+	embedSearcher := em.L.NewFunction(func(L *lua.LState) int {
+		modName := L.CheckString(1)
+
+		fileName := strings.ReplaceAll(modName, ".", "/") + ".lua"
+		embedPath := filepath.Join("lua", fileName)
+
+		bytes, err := embeddedScripts.ReadFile(embedPath)
+		if err != nil {
+			L.Push(lua.LString(fmt.Sprintf("\n\tno embedded file: %s", embedPath)))
+			return 1
+		}
+
+		fn, err := L.LoadString(string(bytes))
+		if err != nil {
+			L.RaiseError("failed to compile embedded module %s: %v", modName, err)
+			return 0
+		}
+
+		L.Push(fn)
+		return 1
+	})
+
+	packageLoaders.Append(embedSearcher)
+}
+
+
 func (em *ExtensionManager) Close() {
 	if em.L != nil {
 		em.L.Close()
@@ -47,6 +103,26 @@ func (em *ExtensionManager) LoadFile(path string) error {
 	return nil
 }
 
+func (em *ExtensionManager) LoadEmbeddedFile(path string) error {
+	if em.L == nil {
+		return fmt.Errorf("lua state is closed")
+	}
+
+	embedPath := filepath.Join("lua", path)
+
+	bytes, err := embeddedScripts.ReadFile(embedPath)
+	if err != nil {
+		return fmt.Errorf("failed to read embedded script %s: %w", path, err)
+	}
+
+	if err := em.L.DoString(string(bytes)); err != nil {
+		return err
+	}
+
+	em.LoadedFiles = append(em.LoadedFiles, path)
+	return nil
+}
+
 func (em *ExtensionManager) LoadString(name string, src string) error {
 	if em.L == nil {
 		return fmt.Errorf("lua state is closed")

+ 2 - 0
internal/extension/lua/init.lua

@@ -0,0 +1,2 @@
+test = require("test")
+test.run()

+ 7 - 0
internal/extension/lua/test.lua

@@ -0,0 +1,7 @@
+local test = {}
+
+test.run = function()
+    print("hihi")
+end
+
+return test