Moved the plugin directory
All checks were successful
Release Build / build (push) Successful in 1m53s

This commit is contained in:
Leon Mika 2026-09-09 21:08:46 +10:00
parent add62fbfa0
commit 9751be125e
5 changed files with 47 additions and 12 deletions

View file

@ -13,8 +13,9 @@ This project uses [Wails](https://wails.io) to build a desktop application with
## Plugins
Dequoter can be extended with new filters written in [UCL](https://ucl.lmika.dev).
On startup, if the directory `$HOME/.config/dequoter/plugins` exists, every file ending in `.ucl`
found in it (including subdirectories) is evaluated. Filters are defined with the `d:filter` builtin:
On startup, Dequoter creates `$HOME/Library/Application Support/dev.lmika.dequoter/plugins` if needed,
then evaluates every file ending in `.ucl` found in it (including subdirectories).
Filters are defined with the `d:filter` builtin:
```
d:filter "String: To Upper Case" { |in|
@ -33,6 +34,8 @@ fail to load are skipped and reported in the status bar; the remaining files are
After editing plugin files, choose File → Reload Plugins (Shift+Cmd+R) to rescan the directory without
restarting. This discards the previous plugin filters and UCL interpreter state before loading the files again.
Use File → Open Plugins in Finder or File → Open Plugins in Terminal to access the directory.
If you have plugins in the old `$HOME/.config/dequoter/plugins` directory, move them to the new location.
## Download

27
app.go
View file

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log"
"os/exec"
"sort"
"strings"
"sync"
@ -96,10 +97,11 @@ func (a *App) loadPluginsFrom(dir string) int {
func (a *App) startup(ctx context.Context) {
a.baseCtx = ctx
dir, err := pluginDir()
dir, err := ensurePluginDir()
if err != nil {
log.Printf("cannot determine plugin directory: %v", err)
a.setUCLInst(newUCLInst(newPluginFilters()), nil)
plugins := newPluginFilters()
plugins.recordError(err)
a.setUCLInst(newUCLInst(plugins), plugins)
return
}
a.loadPluginsFrom(dir)
@ -114,11 +116,11 @@ func (a *App) domReady(ctx context.Context) {
// ReloadPlugins discards the current plugin filters and UCL interpreter, rescans the plugin
// directory, and refreshes the command palette. Invoked from the File menu.
func (a *App) ReloadPlugins() {
dir, err := pluginDir()
dir, err := ensurePluginDir()
if err != nil {
_, _, ctx := a.current()
runtime.EventsEmit(ctx, "set-statusbar-message", SetStatusbarMessage{
Message: fmt.Sprintf("Cannot determine plugin directory: %v", err),
Message: fmt.Sprintf("Cannot prepare plugin directory: %v", err),
Error: true,
})
return
@ -131,6 +133,21 @@ func (a *App) ReloadPlugins() {
a.reportPluginStatus(count, true)
}
// openPluginDir opens the plugin directory using the specified macOS application.
func (a *App) openPluginDir(application string) {
dir, err := ensurePluginDir()
if err == nil {
err = exec.Command("/usr/bin/open", "-a", application, dir).Run()
}
if err != nil {
_, _, ctx := a.current()
runtime.EventsEmit(ctx, "set-statusbar-message", SetStatusbarMessage{
Message: fmt.Sprintf("Cannot open plugins in %s: %v", application, err),
Error: true,
})
}
}
// reportPluginStatus shows plugin load errors in the status bar. If there are no errors and
// reloaded is true, a confirmation message is shown instead.
func (a *App) reportPluginStatus(filterCount int, reloaded bool) {

2
go.sum
View file

@ -796,7 +796,5 @@ lmika.dev/pkg/modash v0.1.0/go.mod h1:8NDl/yR1eCCEhip9FJlVuMNXIeaztQ0Ks/tizExFcT
lmika.dev/pkg/progdoc v0.0.0-20260207235039-984257fb414b h1:uarBEkpjAnpzO98btsA6ZDw9oGnJX8zSb8gZnCFl+6Y=
lmika.dev/pkg/progdoc v0.0.0-20260207235039-984257fb414b/go.mod h1:GefQ+wxW6L0p2TfB4fzoP7ihOgEt5Lb/1qgXhruVHos=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
ucl.lmika.dev v0.1.6 h1:cZocpR/IQcy9nvE8u+SSLY7/PE9fd1HIVWhZr/m+U5M=
ucl.lmika.dev v0.1.6/go.mod h1:Hjl6Udph2yuOPcBSytz4SFJVt5MZbM5JyiSAyTMTbNU=
ucl.lmika.dev v0.1.7 h1:3yfvWOhBnWpQIm4NhKrUBh5PajB1wzUWzoPPa8ltaVo=
ucl.lmika.dev v0.1.7/go.mod h1:Hjl6Udph2yuOPcBSytz4SFJVt5MZbM5JyiSAyTMTbNU=

View file

@ -40,6 +40,12 @@ func main() {
fileMenu.AddText("Reload Plugins", keys.Combo("r", keys.CmdOrCtrlKey, keys.ShiftKey), func(_ *menu.CallbackData) {
app.ReloadPlugins()
})
fileMenu.AddText("Open Plugins in Finder", nil, func(_ *menu.CallbackData) {
app.openPluginDir("Finder")
})
fileMenu.AddText("Open Plugins in Terminal", nil, func(_ *menu.CallbackData) {
app.openPluginDir("Terminal")
})
fileMenu.AddSeparator()
fileMenu.AddText("Quit", keys.CmdOrCtrl("q"), func(_ *menu.CallbackData) {
// `rt` is an alias of "github.com/wailsapp/wails/v2/pkg/runtime" to prevent collision with standard package

View file

@ -173,13 +173,24 @@ func (p *PluginFilters) Errors() []error {
return p.errors
}
// pluginDir returns the plugin directory: $HOME/.config/dequoter/plugins
// pluginDir returns the plugin directory under macOS Application Support.
func pluginDir() (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, ".config", "dequoter", "plugins"), nil
return filepath.Join(home, "Library", "Application Support", "dev.lmika.dequoter", "Plugins"), nil
}
func ensurePluginDir() (string, error) {
dir, err := pluginDir()
if err != nil {
return "", err
}
if err := os.MkdirAll(dir, 0755); err != nil {
return "", fmt.Errorf("create plugin directory: %w", err)
}
return dir, nil
}
var nonSlugChars = regexp.MustCompile(`[^a-z0-9]+`)