Added plugin support for Dequoter
All checks were successful
Release Build / build (push) Successful in 6m59s

This commit is contained in:
Leon Mika 2026-09-07 01:09:21 +00:00
parent cb9c05a57b
commit ac437b7409
5 changed files with 528 additions and 1 deletions

43
app.go
View file

@ -17,13 +17,16 @@ import (
type App struct {
store *Store
uclInst *ucl.Inst
plugins *PluginFilters
ctx context.Context
}
// NewApp creates a new App application struct
func NewApp(store *Store) *App {
plugins := newPluginFilters()
uclInst := ucl.New(
ucl.WithModule(plugins.Module()),
ucl.WithModule(builtins.CSV(nil)),
ucl.WithModule(builtins.Fns()),
ucl.WithModule(builtins.FS(nil)),
@ -37,6 +40,7 @@ func NewApp(store *Store) *App {
return &App{
store: store,
uclInst: uclInst,
plugins: plugins,
}
}
@ -44,6 +48,35 @@ func NewApp(store *Store) *App {
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
a.ctx = context.WithValue(ctx, uclInstKey, a.uclInst)
dir, err := pluginDir()
if err != nil {
log.Printf("cannot determine plugin directory: %v", err)
return
}
a.plugins.LoadDir(a.ctx, a.uclInst, dir)
}
// domReady is called once the frontend has loaded. Reports any plugin load errors in the status bar.
func (a *App) domReady(ctx context.Context) {
errs := a.plugins.Errors()
if len(errs) == 0 {
return
}
runtime.EventsEmit(a.ctx, "set-statusbar-message", SetStatusbarMessage{
Message: fmt.Sprintf("%d plugin file(s) failed to load: %v", len(errs), errs[0]),
Error: true,
})
}
// lookupProcessor finds a text processor by action key, preferring plugin-defined filters.
func (a *App) lookupProcessor(name string) (TextProcessor, bool) {
if proc, ok := a.plugins.filters[name]; ok {
return proc, true
}
proc, ok := TextFilters[name]
return proc, ok
}
func (a *App) LoadCurrentBuffer() (string, error) {
@ -55,7 +88,15 @@ func (a *App) SaveCurrentBuffer(buffer string) error {
}
func (a *App) ListProcessors() (resp []ListProcessorsResponse) {
pluginLabels := make(map[string]struct{}, len(a.plugins.filters))
for k, v := range a.plugins.filters {
pluginLabels[v.Label] = struct{}{}
resp = append(resp, ListProcessorsResponse{Name: k, Label: v.Label})
}
for k, v := range TextFilters {
if _, shadowed := pluginLabels[v.Label]; shadowed {
continue
}
resp = append(resp, ListProcessorsResponse{Name: k, Label: v.Label})
}
sort.Slice(resp, func(i, j int) bool { return resp[i].Label < resp[j].Label })
@ -85,7 +126,7 @@ func (a *App) PromptUser(label string, resp func(string)) {
}
func (a *App) ProcessText(req ProcessTextRequest) {
filter, ok := TextFilters[req.Action]
filter, ok := a.lookupProcessor(req.Action)
if !ok {
log.Printf("Unknown filter: [%s]", req.Action)
return