hyprland/plugins: use HyprlandManager

parent 632abb4d
package hyprland
import (
"ximperconf/config"
"ximperconf/ui"
"ximperconf/utils"
"context"
"encoding/json"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/fatih/color"
"github.com/urfave/cli/v3"
)
type HyprlandPlugin struct {
Name string `json:"name"`
Author string `json:"author"`
Handle string `json:"handle"`
Version string `json:"version"`
Description string `json:"description"`
}
func preparePlugin(cmd *cli.Command) (string, string, error) {
name := cmd.Args().Get(0)
if name == "" {
return "", "", fmt.Errorf("плагин не указан")
}
path := filepath.Join(config.Env.Hyprland.PluginsDir, name+".so")
if !utils.FileExists(path) {
return "", "", fmt.Errorf("плагин не найден")
}
status := hyprlandPluginStatus(name)
return path, status, nil
}
func fetchLoadedPlugins() ([]HyprlandPlugin, error) {
out, err := exec.Command("hyprctl", "plugin", "list", "-j").Output()
if err != nil {
return nil, fmt.Errorf("hyprctl error: %w", err)
}
var plugins []HyprlandPlugin
if err := json.Unmarshal(out, &plugins); err != nil {
return nil, fmt.Errorf("invalid JSON: %w", err)
}
return plugins, nil
}
func hyprlandPluginStatus(plugin string) string {
loaded, err := fetchLoadedPlugins()
if err != nil {
return "error"
}
for _, p := range loaded {
if p.Name == plugin {
return "loaded"
}
}
return "unloaded"
}
func hyprlandPluginStatusStruct(plugin string) ui.ItemStatus {
status := hyprlandPluginStatus(plugin)
func hyprlandPluginStatusStruct(status string) ui.ItemStatus {
switch status {
case "loaded":
return ui.StatusLoaded
......@@ -82,62 +20,52 @@ func hyprlandPluginStatusStruct(plugin string) ui.ItemStatus {
return ui.StatusUnknown
}
func hyprlandPluginList(filter string) []string {
entries, err := os.ReadDir(config.Env.Hyprland.PluginsDir)
func HyprlandPluginListCommand(ctx context.Context, cmd *cli.Command) error {
manager, err := GetHyprlandManager(ctx)
if err != nil {
return nil
}
var list []string
for _, e := range entries {
if e.IsDir() || !strings.HasSuffix(e.Name(), ".so") {
continue
}
name := strings.TrimSuffix(e.Name(), ".so")
status := hyprlandPluginStatus(name)
if filter == "" || filter == "all" || filter == status {
list = append(list, name)
}
}
return list
}
func hyprlandPluginLoad(path string) error {
time.Sleep(1 * time.Second)
cmd := exec.Command("hyprctl", "plugin", "load", path)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v (%s)", err, out)
return err
}
list := manager.GetPluginsList(cmd.String("filter"))
fmt.Println(strings.Join(list, "\n"))
return nil
}
func hyprlandPluginUnload(path string) error {
time.Sleep(1 * time.Second)
cmd := exec.Command("hyprctl", "plugin", "unload", path)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v (%s)", err, out)
func HyprlandPluginStatusCommand(ctx context.Context, cmd *cli.Command) error {
manager, err := GetHyprlandManager(ctx)
if err != nil {
return err
}
fmt.Println(manager.GetPluginStatus(cmd.Args().Get(0)))
return nil
}
func hyprlandPluginInfo(filter string) {
plugins := hyprlandPluginList(filter)
func HyprlandPluginInfoCommand(ctx context.Context, cmd *cli.Command) error {
manager, err := GetHyprlandManager(ctx)
if err != nil {
return err
}
plugins := manager.GetPluginsList(cmd.String("filter"))
if len(plugins) == 0 {
color.Red("Нет доступных плагинов.")
return
return fmt.Errorf("нет доступных плагинов")
}
items := make([]ui.TreeItem, 0, len(plugins))
for _, plugin := range plugins {
status := hyprlandPluginStatusStruct(plugin)
_status := manager.GetPluginStatus(plugin)
status := hyprlandPluginStatusStruct(_status)
desc := ""
if _status == "loaded" {
for _, plug := range manager.LoadedPlugins {
if plug.Name == plugin {
desc = plug.Description
}
}
}
items = append(items, ui.TreeItem{
Name: plugin,
Status: status,
Description: "",
Description: desc,
})
}
......@@ -148,86 +76,61 @@ func hyprlandPluginInfo(filter string) {
StatusMap: ui.ColorStatusMap,
Sort: true,
})
}
func HyprlandPluginListCommand(ctx context.Context, cmd *cli.Command) error {
fmt.Println(strings.Join(hyprlandPluginList(cmd.String("filter")), "\n"))
return nil
}
func HyprlandPluginStatusCommand(ctx context.Context, cmd *cli.Command) error {
fmt.Println(hyprlandPluginStatus(cmd.Args().Get(0)))
return nil
}
func HyprlandPluginInfoCommand(ctx context.Context, cmd *cli.Command) error {
hyprlandPluginInfo(cmd.String("filter"))
return nil
}
func HyprlandPluginLoadCommand(ctx context.Context, cmd *cli.Command) error {
path, status, err := preparePlugin(cmd)
manager, err := GetHyprlandManager(ctx)
if err != nil {
color.Red(err.Error())
return nil
}
if status == "loaded" {
color.Red("плагин уже загружен")
return nil
return err
}
if err := hyprlandPluginLoad(path); err != nil {
color.Red(err.Error())
msg, err := manager.SetPlugin("load", cmd.Args().Get(0))
if err != nil {
return err
}
fmt.Println("OK")
fmt.Println(msg)
return nil
}
func HyprlandPluginUnloadCommand(ctx context.Context, cmd *cli.Command) error {
path, status, err := preparePlugin(cmd)
manager, err := GetHyprlandManager(ctx)
if err != nil {
color.Red(err.Error())
return nil
}
if status == "unloaded" {
color.Red("плагин не загружен")
return nil
return err
}
if err := hyprlandPluginUnload(path); err != nil {
color.Red(err.Error())
msg, err := manager.SetPlugin("unload", cmd.Args().Get(0))
if err != nil {
return err
}
fmt.Println("OK")
fmt.Println(msg)
return nil
}
func HyprlandPluginToggleCommand(ctx context.Context, cmd *cli.Command) error {
path, status, err := preparePlugin(cmd)
manager, err := GetHyprlandManager(ctx)
if err != nil {
color.Red(err.Error())
return nil
return err
}
var execErr error
var msg string
path := cmd.Args().Get(0)
status := manager.GetPluginStatus(path)
switch status {
case "loaded":
execErr = hyprlandPluginUnload(path)
msg, err = manager.SetPlugin("unload", path)
case "unloaded":
execErr = hyprlandPluginLoad(path)
msg, err = manager.SetPlugin("load", path)
}
if execErr != nil {
color.Red(execErr.Error())
return execErr
if err != nil {
return err
}
fmt.Println("OK")
fmt.Println(msg)
return nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment