Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
ximperconf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ximper Linux
ximperconf
Commits
72107231
Verified
Commit
72107231
authored
Feb 14, 2026
by
Kirill Unitsaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
preset: refactor preset system and YAML config format
parent
5b29e43c
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
675 additions
and
802 deletions
+675
-802
config.go
config/config.go
+12
-17
presets.go
config/presets.go
+26
-37
actions.go
hyprland/actions.go
+8
-2
manager.go
hyprland/manager.go
+3
-4
var-actions.go
hyprland/var-actions.go
+1
-2
POTFILES
po/POTFILES
+2
-1
ru.po
po/ru.po
+155
-119
ximperconf.pot
po/ximperconf.pot
+110
-110
actions.go
preset/actions.go
+148
-285
commands.go
preset/commands.go
+15
-32
fileops.go
preset/fileops.go
+50
-106
helpers.go
preset/helpers.go
+58
-39
result.go
preset/result.go
+87
-8
rendertreelines.go
ui/rendertreelines.go
+0
-40
No files found.
config/config.go
View file @
72107231
...
@@ -3,13 +3,8 @@ package config
...
@@ -3,13 +3,8 @@ package config
import
(
import
(
"os"
"os"
"path/filepath"
"path/filepath"
"ximperconf/utils"
)
)
type
presetEnv
struct
{
Profiles
map
[
string
]
PresetProfile
}
type
hyprEnv
struct
{
type
hyprEnv
struct
{
Config
string
Config
string
SystemModulesDir
string
SystemModulesDir
string
...
@@ -24,7 +19,7 @@ type repoEnv struct {
...
@@ -24,7 +19,7 @@ type repoEnv struct {
type
environment
struct
{
type
environment
struct
{
Version
string
Version
string
IsRoot
bool
IsRoot
bool
Pr
eset
*
presetEnv
Pr
ofiles
map
[
string
]
PresetProfile
Hyprland
*
hyprEnv
Hyprland
*
hyprEnv
Repo
*
repoEnv
Repo
*
repoEnv
}
}
...
@@ -35,19 +30,14 @@ func InitConfig() error {
...
@@ -35,19 +30,14 @@ func InitConfig() error {
Env
.
Version
=
"0.1.0"
Env
.
Version
=
"0.1.0"
Env
.
IsRoot
=
os
.
Geteuid
()
==
0
Env
.
IsRoot
=
os
.
Geteuid
()
==
0
pr
esetCfg
,
err
:=
loadPresetConfig
(
"/etc/ximperdistro/ximperconf/preset.d/"
)
pr
ofiles
,
err
:=
loadPresetProfiles
(
"/etc/ximperdistro/ximperconf/preset.d/"
)
if
err
!=
nil
{
if
err
!=
nil
{
// Если ошибка, пустой map
Env
.
Profiles
=
map
[
string
]
PresetProfile
{}
Env
.
Preset
=
&
presetEnv
{
Profiles
:
map
[
string
]
PresetProfile
{},
}
}
else
{
}
else
{
Env
.
Preset
=
&
presetEnv
{
Env
.
Profiles
=
profiles
Profiles
:
presetCfg
.
Profiles
,
}
}
}
if
utils
.
FileExists
(
"/usr/bin/hyprland"
)
{
if
FileExists
(
"/usr/bin/hyprland"
)
{
home
,
_
:=
os
.
UserHomeDir
()
home
,
_
:=
os
.
UserHomeDir
()
userModules
:=
filepath
.
Join
(
home
,
".config"
,
"hypr"
)
userModules
:=
filepath
.
Join
(
home
,
".config"
,
"hypr"
)
systemModules
:=
"/etc/ximperdistro/hyprland/hypr"
systemModules
:=
"/etc/ximperdistro/hyprland/hypr"
...
@@ -63,14 +53,19 @@ func InitConfig() error {
...
@@ -63,14 +53,19 @@ func InitConfig() error {
}
}
Env
.
Repo
=
&
repoEnv
{
Env
.
Repo
=
&
repoEnv
{
DeferredInfoURL
:
"https://download.etersoft.ru/pub/
Etersoft/Sisyphus
/Deferred_Info.html"
,
DeferredInfoURL
:
"https://download.etersoft.ru/pub/
Ximper
/Deferred_Info.html"
,
}
}
return
nil
return
nil
}
}
func
FileExists
(
path
string
)
bool
{
_
,
err
:=
os
.
Stat
(
path
)
return
err
==
nil
}
func
optionalPath
(
path
string
)
string
{
func
optionalPath
(
path
string
)
string
{
if
utils
.
FileExists
(
path
)
{
if
FileExists
(
path
)
{
return
path
return
path
}
}
return
""
return
""
...
...
config/presets.go
View file @
72107231
...
@@ -9,40 +9,39 @@ import (
...
@@ -9,40 +9,39 @@ import (
"gopkg.in/yaml.v3"
"gopkg.in/yaml.v3"
)
)
type
c
opyEntry
struct
{
type
C
opyEntry
struct
{
Src
string
`yaml:"src"`
Src
string
`yaml:"src"`
Dest
string
`yaml:"dest"`
Dest
string
`yaml:"dest"`
}
}
type
linkEntry
struct
{
type
LinkEntry
struct
{
Src
string
`yaml:"src"`
Dest
string
`yaml:"dest"`
Apps
[]
string
`yaml:"apps,omitempty"`
Apps
[]
string
`yaml:"apps,omitempty"`
App
string
`yaml:"app,omitempty"`
Sys
string
`yaml:"sys"`
User
string
`yaml:"user"`
}
}
type
release
ReplaceEntry
struct
{
type
ReplaceEntry
struct
{
Src
string
`yaml:"src"`
Src
string
`yaml:"src"`
Dest
string
`yaml:"dest"`
Dest
string
`yaml:"dest"`
}
}
type
g
rubEntry
struct
{
type
G
rubEntry
struct
{
FixResolution
bool
`yaml:"fix-resolution,omitempty"`
FixResolution
bool
`yaml:"fix-resolution,omitempty"`
Update
bool
`yaml:"update,omitempty"`
Update
bool
`yaml:"update,omitempty"`
}
}
type
s
ystemEntry
struct
{
type
S
ystemEntry
struct
{
Grub
g
rubEntry
`yaml:"grub,omitempty"`
Grub
G
rubEntry
`yaml:"grub,omitempty"`
}
}
type
h
yprVar
struct
{
type
H
yprVar
struct
{
Var
string
`yaml:"var
"`
Name
string
`yaml:"name
"`
Value
string
`yaml:"value"`
Value
string
`yaml:"value"`
Force
bool
`yaml:"force,omitempty"`
Force
bool
`yaml:"force,omitempty"`
}
}
type
h
yprModule
struct
{
type
H
yprModule
struct
{
Module
string
`yaml:"modul
e"`
Name
string
`yaml:"nam
e"`
Action
string
`yaml:"action"`
Action
string
`yaml:"action"`
User
bool
`yaml:"user,omitempty"`
User
bool
`yaml:"user,omitempty"`
NewOnly
bool
`yaml:"new-only,omitempty"`
NewOnly
bool
`yaml:"new-only,omitempty"`
...
@@ -51,35 +50,26 @@ type hyprModule struct {
...
@@ -51,35 +50,26 @@ type hyprModule struct {
Init
bool
`yaml:"init,omitempty"`
Init
bool
`yaml:"init,omitempty"`
}
}
type
hyprOptions
struct
{
type
HyprlandEntry
struct
{
SyncSystemLayouts
bool
`yaml:"sync-system-layouts,omitempty"`
SyncLayouts
bool
`yaml:"sync-layouts,omitempty"`
}
Vars
[]
HyprVar
`yaml:"vars,omitempty"`
Modules
[]
HyprModule
`yaml:"modules,omitempty"`
type
hyprlandEntry
struct
{
Option
hyprOptions
`yaml:"options,omitempty"`
Vars
[]
hyprVar
`yaml:"vars,omitempty"`
Modules
[]
hyprModule
`yaml:"modules,omitempty"`
}
}
type
PresetProfile
struct
{
type
PresetProfile
struct
{
Binary
string
`yaml:"binary,omitempty"`
Binary
string
`yaml:"binary,omitempty"`
Description
string
`yaml:"description,omitempty"`
Description
string
`yaml:"description,omitempty"`
Root
bool
`yaml:"root,omitempty"`
Root
bool
`yaml:"root,omitempty"`
Copy
[]
copyEntry
`yaml:"copy,omitempty"`
Priority
int
`yaml:"priority,omitempty"`
Links
[]
linkEntry
`yaml:"links,omitempty"`
Copy
[]
CopyEntry
`yaml:"copy,omitempty"`
ReleaseReplace
[]
releaseReplaceEntry
`yaml:"release-replace,omitempty"`
Links
[]
LinkEntry
`yaml:"links,omitempty"`
System
systemEntry
`yaml:"system,omitempty"`
Replace
[]
ReplaceEntry
`yaml:"replace,omitempty"`
System
SystemEntry
`yaml:"system,omitempty"`
// ----- hyprland -----
Hyprland
HyprlandEntry
`yaml:"hyprland,omitempty"`
Hyprland
hyprlandEntry
`yaml:"hyprland,omitempty"`
}
type
Presets
struct
{
Profiles
map
[
string
]
PresetProfile
`yaml:"profiles"`
}
}
func
loadPreset
Config
(
dir
string
)
(
*
Presets
,
error
)
{
func
loadPreset
Profiles
(
dir
string
)
(
map
[
string
]
PresetProfile
,
error
)
{
cfg
:=
&
Presets
{
Profiles
:
map
[
string
]
PresetProfile
{}
}
profiles
:=
map
[
string
]
PresetProfile
{
}
entries
,
err
:=
os
.
ReadDir
(
dir
)
entries
,
err
:=
os
.
ReadDir
(
dir
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -108,9 +98,8 @@ func loadPresetConfig(dir string) (*Presets, error) {
...
@@ -108,9 +98,8 @@ func loadPresetConfig(dir string) (*Presets, error) {
}
}
profileName
:=
strings
.
TrimSuffix
(
name
,
filepath
.
Ext
(
name
))
profileName
:=
strings
.
TrimSuffix
(
name
,
filepath
.
Ext
(
name
))
profiles
[
profileName
]
=
p
cfg
.
Profiles
[
profileName
]
=
p
}
}
return
cfg
,
nil
return
profiles
,
nil
}
}
hyprland/actions.go
View file @
72107231
...
@@ -4,7 +4,6 @@ import (
...
@@ -4,7 +4,6 @@ import (
"ximperconf/config"
"ximperconf/config"
"ximperconf/locale"
"ximperconf/locale"
"ximperconf/ui"
"ximperconf/ui"
"ximperconf/utils"
"context"
"context"
"errors"
"errors"
...
@@ -267,7 +266,7 @@ func HyprlandModuleEditCommand(ctx context.Context, cmd *cli.Command) error {
...
@@ -267,7 +266,7 @@ func HyprlandModuleEditCommand(ctx context.Context, cmd *cli.Command) error {
return
fmt
.
Errorf
(
locale
.
T
(
"module '%s' not found: %s"
),
module
,
modulefile
)
return
fmt
.
Errorf
(
locale
.
T
(
"module '%s' not found: %s"
),
module
,
modulefile
)
}
}
editor
:=
utils
.
G
etEditor
()
editor
:=
g
etEditor
()
editCmd
:=
exec
.
Command
(
editor
,
modulefile
)
editCmd
:=
exec
.
Command
(
editor
,
modulefile
)
editCmd
.
Stdin
=
os
.
Stdin
editCmd
.
Stdin
=
os
.
Stdin
...
@@ -344,3 +343,10 @@ func HyprlandModuleShowCommand(ctx context.Context, cmd *cli.Command) error {
...
@@ -344,3 +343,10 @@ func HyprlandModuleShowCommand(ctx context.Context, cmd *cli.Command) error {
return
nil
return
nil
}
}
func
getEditor
()
string
{
if
editor
:=
os
.
Getenv
(
"EDITOR"
);
editor
!=
""
{
return
editor
}
return
"micro"
}
hyprland/manager.go
View file @
72107231
...
@@ -13,7 +13,6 @@ import (
...
@@ -13,7 +13,6 @@ import (
"time"
"time"
"ximperconf/config"
"ximperconf/config"
"ximperconf/locale"
"ximperconf/locale"
"ximperconf/utils"
)
)
type
HyprlandManager
struct
{
type
HyprlandManager
struct
{
...
@@ -193,10 +192,10 @@ func (m *HyprlandManager) GetModuleInfo(module string, user bool) HyprModule {
...
@@ -193,10 +192,10 @@ func (m *HyprlandManager) GetModuleInfo(module string, user bool) HyprModule {
}
}
}
}
FileExists
:=
utils
.
FileExists
(
sysFile
)
FileExists
:=
config
.
FileExists
(
sysFile
)
// Конфиг Hyprland отсутствует
// Конфиг Hyprland отсутствует
if
!
utils
.
FileExists
(
config
.
Env
.
Hyprland
.
Config
)
{
if
!
config
.
FileExists
(
config
.
Env
.
Hyprland
.
Config
)
{
if
FileExists
{
if
FileExists
{
return
HyprModule
{
return
HyprModule
{
Name
:
module
,
Name
:
module
,
...
@@ -796,7 +795,7 @@ func (m *HyprlandManager) GetPluginFile(name string) (string, error) {
...
@@ -796,7 +795,7 @@ func (m *HyprlandManager) GetPluginFile(name string) (string, error) {
}
}
path
:=
filepath
.
Join
(
m
.
PluginsDir
,
name
+
".so"
)
path
:=
filepath
.
Join
(
m
.
PluginsDir
,
name
+
".so"
)
if
!
utils
.
FileExists
(
path
)
{
if
!
config
.
FileExists
(
path
)
{
return
""
,
errors
.
New
(
locale
.
T
(
"plugin not found"
))
return
""
,
errors
.
New
(
locale
.
T
(
"plugin not found"
))
}
}
...
...
hyprland/var-actions.go
View file @
72107231
...
@@ -5,7 +5,6 @@ import (
...
@@ -5,7 +5,6 @@ import (
"ximperconf/config"
"ximperconf/config"
"ximperconf/locale"
"ximperconf/locale"
"ximperconf/ui"
"ximperconf/ui"
"ximperconf/utils"
"fmt"
"fmt"
"os"
"os"
...
@@ -121,7 +120,7 @@ func hyprlandVarUnset(name string) error {
...
@@ -121,7 +120,7 @@ func hyprlandVarUnset(name string) error {
color
.
Red
(
locale
.
T
(
"Invalid variable name: %s"
),
name
)
color
.
Red
(
locale
.
T
(
"Invalid variable name: %s"
),
name
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
if
!
utils
.
FileExists
(
config
.
Env
.
Hyprland
.
Config
)
{
if
!
config
.
FileExists
(
config
.
Env
.
Hyprland
.
Config
)
{
color
.
Red
(
locale
.
T
(
"Configuration not found: %s"
),
config
.
Env
.
Hyprland
.
Config
)
color
.
Red
(
locale
.
T
(
"Configuration not found: %s"
),
config
.
Env
.
Hyprland
.
Config
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
...
...
po/POTFILES
View file @
72107231
...
@@ -7,7 +7,8 @@ hyprland/var-actions.go
...
@@ -7,7 +7,8 @@ hyprland/var-actions.go
main.go
main.go
preset/actions.go
preset/actions.go
preset/commands.go
preset/commands.go
preset/tools.go
preset/helpers.go
preset/result.go
repo/actions.go
repo/actions.go
repo/commands.go
repo/commands.go
system/commands.go
system/commands.go
...
...
po/ru.po
View file @
72107231
...
@@ -6,7 +6,7 @@ msgid ""
...
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
msgstr ""
"Project-Id-Version: ximperconf\n"
"Project-Id-Version: ximperconf\n"
"Report-Msgid-Bugs-To: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-14
18:34
+0300\n"
"POT-Creation-Date: 2026-02-14
21:56
+0300\n"
"PO-Revision-Date: 2026-02-14 17:13+0300\n"
"PO-Revision-Date: 2026-02-14 17:13+0300\n"
"Last-Translator: \n"
"Last-Translator: \n"
"Language-Team: Russian\n"
"Language-Team: Russian\n"
...
@@ -229,21 +229,21 @@ msgstr "выгрузить плагин"
...
@@ -229,21 +229,21 @@ msgstr "выгрузить плагин"
msgid "toggle plugin"
msgid "toggle plugin"
msgstr "переключить плагин"
msgstr "переключить плагин"
#: hyprland/keyboard-actions.go:4
2
#: hyprland/keyboard-actions.go:4
3
msgid "failed to get system layouts: %w"
msgid "failed to get system layouts: %w"
msgstr "не удалось получить системные раскладки: %w"
msgstr "не удалось получить системные раскладки: %w"
#: hyprland/keyboard-actions.go:
49
#: hyprland/keyboard-actions.go:
50
msgid "failed to update kb_layout in Hyprland: %w"
msgid "failed to update kb_layout in Hyprland: %w"
msgstr "не удалось обновить kb_layout в Hyprland: %w"
msgstr "не удалось обновить kb_layout в Hyprland: %w"
#: hyprland/keyboard-actions.go:5
1
#: hyprland/keyboard-actions.go:5
2
msgid "Layout updated!"
msgid "Layout updated!"
msgstr "Раскладка обновлена!"
msgstr "Раскладка обновлена!"
#: hyprland/keyboard-actions.go:5
3
#: hyprland/keyboard-actions.go:5
4
msgid "layout is already set, use '--force' for forced update"
msgid "layout is already set, use '--force' for forced update"
msgstr ""
msgstr "
раскладка уже установлена, используйте '--force' для принудительного обновления
"
"раскладка уже установлена, используйте '--force' для принудительного "
"раскладка уже установлена, используйте '--force' для принудительного "
"обновления"
"обновления"
...
@@ -284,7 +284,7 @@ msgstr "модуль '%s' не изменён"
...
@@ -284,7 +284,7 @@ msgstr "модуль '%s' не изменён"
msgid "module '%s' is already disabled"
msgid "module '%s' is already disabled"
msgstr "модуль '%s' уже отключён"
msgstr "модуль '%s' уже отключён"
#: hyprland/manager.go:416
preset/actions.go:240 preset/actions.go:267
#: hyprland/manager.go:416
#, c-format
#, c-format
msgid "Module '%s' disabled"
msgid "Module '%s' disabled"
msgstr "Модуль '%s' отключён"
msgstr "Модуль '%s' отключён"
...
@@ -294,12 +294,12 @@ msgstr "Модуль '%s' отключён"
...
@@ -294,12 +294,12 @@ msgstr "Модуль '%s' отключён"
msgid "module '%s' not found in config"
msgid "module '%s' not found in config"
msgstr "модуль '%s' не найден в конфигурации"
msgstr "модуль '%s' не найден в конфигурации"
#: hyprland/manager.go:428
preset/actions.go:242 preset/actions.go:269
#: hyprland/manager.go:428
#, c-format
#, c-format
msgid "Module '%s' removed"
msgid "Module '%s' removed"
msgstr "Модуль '%s' удалён"
msgstr "Модуль '%s' удалён"
#: hyprland/manager.go:434
preset/actions.go:238 preset/actions.go:265
#: hyprland/manager.go:434
#, c-format
#, c-format
msgid "Module '%s' enabled"
msgid "Module '%s' enabled"
msgstr "Модуль '%s' включён"
msgstr "Модуль '%s' включён"
...
@@ -343,7 +343,7 @@ msgstr "плагин не загружен"
...
@@ -343,7 +343,7 @@ msgstr "плагин не загружен"
msgid "Plugin '%s' unloaded"
msgid "Plugin '%s' unloaded"
msgstr "Плагин '%s' выгружен"
msgstr "Плагин '%s' выгружен"
#: hyprland/manager.go:886 hyprland/manager.go:925 hyprland/var-actions.go:11
7
#: hyprland/manager.go:886 hyprland/manager.go:925 hyprland/var-actions.go:11
6
msgid "specify variable name"
msgid "specify variable name"
msgstr "укажите имя переменной"
msgstr "укажите имя переменной"
...
@@ -371,43 +371,43 @@ msgstr "Переменная '%s' установлена: %s"
...
@@ -371,43 +371,43 @@ msgstr "Переменная '%s' установлена: %s"
msgid "VARS block created, variable '%s' set: %s"
msgid "VARS block created, variable '%s' set: %s"
msgstr "Блок VARS создан, переменная '%s' установлена: %s"
msgstr "Блок VARS создан, переменная '%s' установлена: %s"
#: hyprland/manager.go:935 hyprland/var-actions.go:14
5
#: hyprland/manager.go:935 hyprland/var-actions.go:14
4
#, c-format
#, c-format
msgid "variable '%s' not found"
msgid "variable '%s' not found"
msgstr "переменная '%s' не найдена"
msgstr "переменная '%s' не найдена"
#: hyprland/plugin-actions.go:5
3
#: hyprland/plugin-actions.go:5
4
msgid "no available plugins"
msgid "no available plugins"
msgstr "нет доступных плагинов"
msgstr "нет доступных плагинов"
#: hyprland/plugin-actions.go:8
0
#: hyprland/plugin-actions.go:8
1
msgid "Plugins"
msgid "Plugins"
msgstr "Плагины"
msgstr "Плагины"
#: hyprland/var-actions.go:5
2
#: hyprland/var-actions.go:5
1
msgid "No variables in configuration"
msgid "No variables in configuration"
msgstr "Нет переменных в конфигурации"
msgstr "Нет переменных в конфигурации"
#: hyprland/var-actions.go:7
7
#: hyprland/var-actions.go:7
6
msgid "Vars"
msgid "Vars"
msgstr "Переменные"
msgstr "Переменные"
#: hyprland/var-actions.go:9
4
#: hyprland/var-actions.go:9
3
#, c-format
#, c-format
msgid "variable '%s' is not set"
msgid "variable '%s' is not set"
msgstr "переменная '%s' не установлена"
msgstr "переменная '%s' не установлена"
#: hyprland/var-actions.go:12
1
#: hyprland/var-actions.go:12
0
#, c-format
#, c-format
msgid "Invalid variable name: %s"
msgid "Invalid variable name: %s"
msgstr "Недопустимое имя переменной: %s"
msgstr "Недопустимое имя переменной: %s"
#: hyprland/var-actions.go:12
5
#: hyprland/var-actions.go:12
4
#, c-format
#, c-format
msgid "Configuration not found: %s"
msgid "Configuration not found: %s"
msgstr "Конфигурация не найдена: %s"
msgstr "Конфигурация не найдена: %s"
#: hyprland/var-actions.go:14
9
#: hyprland/var-actions.go:14
8
#, c-format
#, c-format
msgid "Variable '%s' removed"
msgid "Variable '%s' removed"
msgstr "Переменная '%s' удалена"
msgstr "Переменная '%s' удалена"
...
@@ -420,194 +420,194 @@ msgstr "Инструмент настройки Ximper Linux"
...
@@ -420,194 +420,194 @@ msgstr "Инструмент настройки Ximper Linux"
msgid "show help"
msgid "show help"
msgstr "показать справку"
msgstr "показать справку"
#: preset/actions.go:77
#: preset/actions.go:30
msgid "copy"
msgstr "копия"
#: preset/actions.go:40
msgid "link"
msgstr "ссылка"
#: preset/actions.go:64
msgid "replace"
msgstr "замена"
#: preset/actions.go:70
#, c-format
#, c-format
msgid "Not found: '%s'"
msgid "Not found: '%s'"
msgstr "Не найден: '%s'"
msgstr "Не найден: '%s'"
#: preset/actions.go:
8
5
#: preset/actions.go:
7
5
msgid "Failed to read %s: %v"
msgid "Failed to read %s: %v"
msgstr "Не удалось прочитать %s: %v"
msgstr "Не удалось прочитать %s: %v"
#: preset/actions.go:
93
#: preset/actions.go:
79
#, c-format
#, c-format
msgid "Locked: %s"
msgid "Locked: %s"
msgstr "Заблокирован: %s"
msgstr "Заблокирован: %s"
#: preset/actions.go:
105
#: preset/actions.go:
88
#, c-format
#, c-format
msgid "Up to date: '%s'"
msgid "Up to date: '%s'"
msgstr "Актуально: '%s'"
msgstr "Актуально: '%s'"
#: preset/actions.go:
120
#: preset/actions.go:
97
msgid "Replace error %s: %v"
msgid "Replace error %s: %v"
msgstr "Ошибка замены %s: %v"
msgstr "Ошибка замены %s: %v"
#: preset/actions.go:136 preset/tools.go:45
#: preset/actions.go:111 preset/actions.go:113 preset/actions.go:119
#: preset/actions.go:123 preset/actions.go:125
msgid "system"
msgstr "система"
#: preset/actions.go:119
msgid "GRUB error: %v"
msgstr "Ошибка GRUB: %v"
#: preset/actions.go:123 system/grub-actions.go:86
msgid "GRUB_GFXMODE fixed"
msgstr "GRUB_GFXMODE исправлен"
#: preset/actions.go:125 system/grub-actions.go:89
msgid "update-grub completed"
msgstr "update-grub выполнен"
#: preset/actions.go:133 preset/actions.go:139 preset/actions.go:144
#: preset/actions.go:146
msgid "var"
msgstr "переменная"
#: preset/actions.go:133
#, c-format
#, c-format
msgid "Already exists: %s"
msgid "Already exists: %s"
msgstr "Уже существует: %s"
msgstr "Уже существует: %s"
#: preset/actions.go:1
53
#: preset/actions.go:1
44
msgid "Error setting %s: %v"
msgid "Error setting %s: %v"
msgstr "Ошибка установки %s: %v"
msgstr "Ошибка установки %s: %v"
#: preset/actions.go:170
#: preset/actions.go:154 preset/actions.go:159 preset/actions.go:167
#: preset/actions.go:173 preset/actions.go:181 preset/actions.go:184
#: preset/actions.go:190 preset/actions.go:195 preset/actions.go:197
msgid "module"
msgstr "модуль"
#: preset/actions.go:154
msgid "Skipped module without name"
msgid "Skipped module without name"
msgstr "Пропущен модуль без имени"
msgstr "Пропущен модуль без имени"
#: preset/actions.go:1
78
#: preset/actions.go:1
59
#, c-format
#, c-format
msgid "Module '%s': unsupported action"
msgid "Module '%s': unsupported action"
msgstr "Модуль '%s': неподдерживаемый action"
msgstr "Модуль '%s': неподдерживаемый action"
#: preset/actions.go:1
90
#: preset/actions.go:1
67
#, c-format
#, c-format
msgid "Module '%s': co
mmand '%s' failed
"
msgid "Module '%s': co
ndition not met
"
msgstr "Модуль '%s':
команда '%s' завершилась с ошибкой
"
msgstr "Модуль '%s':
условие не выполнено
"
#: preset/actions.go:198
#: preset/actions.go:173
#, c-format
msgid "Module '%s': command '%s' returned no data"
msgstr "Модуль '%s': команда '%s' не вернула данных"
#: preset/actions.go:208
#, c-format
#, c-format
msgid "Module '%s': binary '%s' not found"
msgid "Module '%s': binary '%s' not found"
msgstr "Модуль '%s': бинарник '%s' не найден"
msgstr "Модуль '%s': бинарник '%s' не найден"
#: preset/actions.go:
220 preset/actions.go:226
#: preset/actions.go:
181 preset/actions.go:184
#, c-format
#, c-format
msgid "Created empty module: %s"
msgid "Created empty module: %s"
msgstr "Создан пустой модуль: %s"
msgstr "Создан пустой модуль: %s"
#: preset/actions.go:
258
#: preset/actions.go:
195
msgid "Error (%s): %v"
msgid "Error (%s): %v"
msgstr "Ошибка (%s): %v"
msgstr "Ошибка (%s): %v"
#: preset/actions.go:286
#: preset/actions.go:208 preset/actions.go:214 preset/actions.go:222
#: preset/actions.go:225 preset/actions.go:227
msgid "layout"
msgstr "раскладка"
#: preset/actions.go:208
msgid "Sync Hyprland layouts"
msgid "Sync Hyprland layouts"
msgstr "Синхронизация раскладок Hyprland"
msgstr "Синхронизация раскладок Hyprland"
#: preset/actions.go:2
95
#: preset/actions.go:2
14
msgid "Failed to get system layouts"
msgid "Failed to get system layouts"
msgstr "Не удалось получить системные раскладки"
msgstr "Не удалось получить системные раскладки"
#: preset/actions.go:308
#: preset/actions.go:222
#, c-format
msgid "XCB layout: %s"
msgstr "Раскладка XCB: %s"
#: preset/actions.go:312
#, c-format
msgid "Hyprland layout: %s"
msgstr "Раскладка Hyprland: %s"
#: preset/actions.go:319
msgid "Failed to update kb_layout"
msgid "Failed to update kb_layout"
msgstr "Не удалось обновить kb_layout"
msgstr "Не удалось обновить kb_layout"
#: preset/actions.go:
3
25
#: preset/actions.go:
2
25
#, c-format
#, c-format
msgid "Layout updated: %s"
msgid "Layout updated: %s"
msgstr "Раскладка обновлена: %s"
msgstr "Раскладка обновлена: %s"
#: preset/actions.go:
330
#: preset/actions.go:
227
#, c-format
#, c-format
msgid "Layout already set: %s"
msgid "Layout already set: %s"
msgstr "Раскладка уже установлена: %s"
msgstr "Раскладка уже установлена: %s"
#: preset/actions.go:354
#: preset/actions.go:270
msgid "GRUB error: %v"
msgstr "Ошибка GRUB: %v"
#: preset/actions.go:359 system/grub-actions.go:86
msgid "GRUB_GFXMODE fixed"
msgstr "GRUB_GFXMODE исправлен"
#: preset/actions.go:364 system/grub-actions.go:89
msgid "update-grub completed"
msgstr "update-grub выполнен"
#: preset/actions.go:392
#, c-format
#, c-format
msgid "
Creating profile: %s
"
msgid "
Profile %s not found
"
msgstr "
Создаётся профиль: %s
"
msgstr "
Профиль %s не найден
"
#: preset/actions.go:
394
#: preset/actions.go:
275
#, c-format
#, c-format
msgid "Profile %s unavailable"
msgid "Profile %s unavailable"
msgstr "Профиль %s недоступен"
msgstr "Профиль %s недоступен"
#: preset/actions.go:408 preset/actions.go:468
#: preset/actions.go:287 preset/actions.go:338
#, c-format
msgid "Applying profile: %s"
msgstr "Применяем профиль: %s"
#: preset/actions.go:321 preset/helpers.go:73
msgid "no available profiles"
msgid "no available profiles"
msgstr "нет доступных профилей"
msgstr "нет доступных профилей"
#: preset/actions.go:430
#: preset/commands.go:13
msgid "Profiles"
msgid "Show what would be created without making changes"
msgstr "Профили"
msgstr "Показать что будет создано без внесения изменений"
#: preset/actions.go:451
#, c-format
msgid "Profile %s not found"
msgstr "Профиль %s не найден"
#: preset/
actions.go:472
#: preset/
commands.go:18
msgid "
Creating all available profiles...
"
msgid "
Force overwrite existing files (backup to .bak)
"
msgstr "
Создаём все доступные профили...
"
msgstr "
Принудительная перезапись файлов (бэкап в .bak)
"
#: preset/commands.go:
15
#: preset/commands.go:
26
msgid "Manage preset configuration profiles"
msgid "Manage preset configuration profiles"
msgstr "Управление профилями конфигурации"
msgstr "Управление профилями конфигурации"
#: preset/commands.go:
19
#: preset/commands.go:
30
msgid "Show information about preset profiles"
msgid "Show information about preset profiles"
msgstr "Показать информацию о профилях"
msgstr "Показать информацию о профилях"
#: preset/commands.go:
27
#: preset/commands.go:
38
msgid "Apply a profile"
msgid "Apply a profile"
msgstr "Применить профиль"
msgstr "Применить профиль"
#: preset/commands.go:31 preset/commands.go:45
#: preset/commands.go:45
msgid "Show what would be created without making changes"
msgstr "Показать что будет создано без внесения изменений"
#: preset/commands.go:41
msgid "Apply all available profiles"
msgid "Apply all available profiles"
msgstr "Применить все доступные профили"
msgstr "Применить все доступные профили"
#: preset/tools.go:51
#: preset/helpers.go:93
#, c-format
msgid "Profiles"
msgid "Error: %s"
msgstr "Профили"
msgstr "Ошибка: %s"
#: preset/tools.go:85
msgid "Copying"
msgstr "Копируем"
#: preset/tools.go:86
msgid "Creating links"
msgstr "Создаём ссылки"
#: preset/tools.go:87
msgid "Updating"
msgstr "Обновляем"
#: preset/tools.go:88
msgid "Configuring system"
msgstr "Настраиваем систему"
#: preset/
tools.go:89
#: preset/
result.go:74
msgid "
Creating Hyprland variables
"
msgid "
done
"
msgstr "
Создаём переменные Hyprland
"
msgstr "
выполнено
"
#: preset/
tools.go:90
#: preset/
result.go:77
msgid "
Enabling Hyprland modules
"
msgid "
skipped
"
msgstr "
Подключаем модули Hyprland
"
msgstr "
пропущено
"
#: preset/tools.go:91
#: preset/result.go:80
msgid "Syncing Hyprland layout"
msgid "error"
msgstr "Синхронизируем раскладку Hyprland"
msgid_plural "errors"
msgstr[0] "ошибка"
msgstr[1] "ошибки"
msgstr[2] "ошибок"
#: repo/actions.go:31 repo/actions.go:38
#: repo/actions.go:31 repo/actions.go:38
msgid "Error fetching data"
msgid "Error fetching data"
...
@@ -718,3 +718,39 @@ msgstr "Глобальные параметры:"
...
@@ -718,3 +718,39 @@ msgstr "Глобальные параметры:"
#: ui/help.go:125
#: ui/help.go:125
msgid "default"
msgid "default"
msgstr "по умолчанию"
msgstr "по умолчанию"
#, c-format
#~ msgid "Module '%s': command '%s' failed"
#~ msgstr "Модуль '%s': команда '%s' завершилась с ошибкой"
#, c-format
#~ msgid "Hyprland layout: %s"
#~ msgstr "Раскладка Hyprland: %s"
#~ msgid "Creating all available profiles..."
#~ msgstr "Создаём все доступные профили..."
#, c-format
#~ msgid "Error: %s"
#~ msgstr "Ошибка: %s"
#~ msgid "Copying"
#~ msgstr "Копируем"
#~ msgid "Creating links"
#~ msgstr "Создаём ссылки"
#~ msgid "Updating"
#~ msgstr "Обновляем"
#~ msgid "Configuring system"
#~ msgstr "Настраиваем систему"
#~ msgid "Creating Hyprland variables"
#~ msgstr "Создаём переменные Hyprland"
#~ msgid "Enabling Hyprland modules"
#~ msgstr "Подключаем модули Hyprland"
#~ msgid "Syncing Hyprland layout"
#~ msgstr "Синхронизируем раскладку Hyprland"
po/ximperconf.pot
View file @
72107231
...
@@ -8,7 +8,7 @@ msgid ""
...
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
msgstr ""
"Project-Id-Version: ximperconf\n"
"Project-Id-Version: ximperconf\n"
"Report-Msgid-Bugs-To: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-14
18:34
+0300\n"
"POT-Creation-Date: 2026-02-14
21:56
+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
...
@@ -16,6 +16,7 @@ msgstr ""
...
@@ -16,6 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: hyprland/actions.go:27
#: hyprland/actions.go:27
msgid "Configuration fixed"
msgid "Configuration fixed"
...
@@ -229,19 +230,19 @@ msgstr ""
...
@@ -229,19 +230,19 @@ msgstr ""
msgid "toggle plugin"
msgid "toggle plugin"
msgstr ""
msgstr ""
#: hyprland/keyboard-actions.go:4
2
#: hyprland/keyboard-actions.go:4
3
msgid "failed to get system layouts: %w"
msgid "failed to get system layouts: %w"
msgstr ""
msgstr ""
#: hyprland/keyboard-actions.go:
49
#: hyprland/keyboard-actions.go:
50
msgid "failed to update kb_layout in Hyprland: %w"
msgid "failed to update kb_layout in Hyprland: %w"
msgstr ""
msgstr ""
#: hyprland/keyboard-actions.go:5
1
#: hyprland/keyboard-actions.go:5
2
msgid "Layout updated!"
msgid "Layout updated!"
msgstr ""
msgstr ""
#: hyprland/keyboard-actions.go:5
3
#: hyprland/keyboard-actions.go:5
4
msgid "layout is already set, use '--force' for forced update"
msgid "layout is already set, use '--force' for forced update"
msgstr ""
msgstr ""
...
@@ -282,7 +283,7 @@ msgstr ""
...
@@ -282,7 +283,7 @@ msgstr ""
msgid "module '%s' is already disabled"
msgid "module '%s' is already disabled"
msgstr ""
msgstr ""
#: hyprland/manager.go:416
preset/actions.go:240 preset/actions.go:267
#: hyprland/manager.go:416
#, c-format
#, c-format
msgid "Module '%s' disabled"
msgid "Module '%s' disabled"
msgstr ""
msgstr ""
...
@@ -292,12 +293,12 @@ msgstr ""
...
@@ -292,12 +293,12 @@ msgstr ""
msgid "module '%s' not found in config"
msgid "module '%s' not found in config"
msgstr ""
msgstr ""
#: hyprland/manager.go:428
preset/actions.go:242 preset/actions.go:269
#: hyprland/manager.go:428
#, c-format
#, c-format
msgid "Module '%s' removed"
msgid "Module '%s' removed"
msgstr ""
msgstr ""
#: hyprland/manager.go:434
preset/actions.go:238 preset/actions.go:265
#: hyprland/manager.go:434
#, c-format
#, c-format
msgid "Module '%s' enabled"
msgid "Module '%s' enabled"
msgstr ""
msgstr ""
...
@@ -339,7 +340,7 @@ msgstr ""
...
@@ -339,7 +340,7 @@ msgstr ""
msgid "Plugin '%s' unloaded"
msgid "Plugin '%s' unloaded"
msgstr ""
msgstr ""
#: hyprland/manager.go:886 hyprland/manager.go:925 hyprland/var-actions.go:11
7
#: hyprland/manager.go:886 hyprland/manager.go:925 hyprland/var-actions.go:11
6
msgid "specify variable name"
msgid "specify variable name"
msgstr ""
msgstr ""
...
@@ -367,43 +368,43 @@ msgstr ""
...
@@ -367,43 +368,43 @@ msgstr ""
msgid "VARS block created, variable '%s' set: %s"
msgid "VARS block created, variable '%s' set: %s"
msgstr ""
msgstr ""
#: hyprland/manager.go:935 hyprland/var-actions.go:14
5
#: hyprland/manager.go:935 hyprland/var-actions.go:14
4
#, c-format
#, c-format
msgid "variable '%s' not found"
msgid "variable '%s' not found"
msgstr ""
msgstr ""
#: hyprland/plugin-actions.go:5
3
#: hyprland/plugin-actions.go:5
4
msgid "no available plugins"
msgid "no available plugins"
msgstr ""
msgstr ""
#: hyprland/plugin-actions.go:8
0
#: hyprland/plugin-actions.go:8
1
msgid "Plugins"
msgid "Plugins"
msgstr ""
msgstr ""
#: hyprland/var-actions.go:5
2
#: hyprland/var-actions.go:5
1
msgid "No variables in configuration"
msgid "No variables in configuration"
msgstr ""
msgstr ""
#: hyprland/var-actions.go:7
7
#: hyprland/var-actions.go:7
6
msgid "Vars"
msgid "Vars"
msgstr ""
msgstr ""
#: hyprland/var-actions.go:9
4
#: hyprland/var-actions.go:9
3
#, c-format
#, c-format
msgid "variable '%s' is not set"
msgid "variable '%s' is not set"
msgstr ""
msgstr ""
#: hyprland/var-actions.go:12
1
#: hyprland/var-actions.go:12
0
#, c-format
#, c-format
msgid "Invalid variable name: %s"
msgid "Invalid variable name: %s"
msgstr ""
msgstr ""
#: hyprland/var-actions.go:12
5
#: hyprland/var-actions.go:12
4
#, c-format
#, c-format
msgid "Configuration not found: %s"
msgid "Configuration not found: %s"
msgstr ""
msgstr ""
#: hyprland/var-actions.go:14
9
#: hyprland/var-actions.go:14
8
#, c-format
#, c-format
msgid "Variable '%s' removed"
msgid "Variable '%s' removed"
msgstr ""
msgstr ""
...
@@ -416,194 +417,193 @@ msgstr ""
...
@@ -416,194 +417,193 @@ msgstr ""
msgid "show help"
msgid "show help"
msgstr ""
msgstr ""
#: preset/actions.go:77
#: preset/actions.go:30
msgid "copy"
msgstr ""
#: preset/actions.go:40
msgid "link"
msgstr ""
#: preset/actions.go:64
msgid "replace"
msgstr ""
#: preset/actions.go:70
#, c-format
#, c-format
msgid "Not found: '%s'"
msgid "Not found: '%s'"
msgstr ""
msgstr ""
#: preset/actions.go:
8
5
#: preset/actions.go:
7
5
msgid "Failed to read %s: %v"
msgid "Failed to read %s: %v"
msgstr ""
msgstr ""
#: preset/actions.go:
93
#: preset/actions.go:
79
#, c-format
#, c-format
msgid "Locked: %s"
msgid "Locked: %s"
msgstr ""
msgstr ""
#: preset/actions.go:
105
#: preset/actions.go:
88
#, c-format
#, c-format
msgid "Up to date: '%s'"
msgid "Up to date: '%s'"
msgstr ""
msgstr ""
#: preset/actions.go:
120
#: preset/actions.go:
97
msgid "Replace error %s: %v"
msgid "Replace error %s: %v"
msgstr ""
msgstr ""
#: preset/actions.go:136 preset/tools.go:45
#: preset/actions.go:111 preset/actions.go:113 preset/actions.go:119
#: preset/actions.go:123 preset/actions.go:125
msgid "system"
msgstr ""
#: preset/actions.go:119
msgid "GRUB error: %v"
msgstr ""
#: preset/actions.go:123 system/grub-actions.go:86
msgid "GRUB_GFXMODE fixed"
msgstr ""
#: preset/actions.go:125 system/grub-actions.go:89
msgid "update-grub completed"
msgstr ""
#: preset/actions.go:133 preset/actions.go:139 preset/actions.go:144
#: preset/actions.go:146
msgid "var"
msgstr ""
#: preset/actions.go:133
#, c-format
#, c-format
msgid "Already exists: %s"
msgid "Already exists: %s"
msgstr ""
msgstr ""
#: preset/actions.go:1
53
#: preset/actions.go:1
44
msgid "Error setting %s: %v"
msgid "Error setting %s: %v"
msgstr ""
msgstr ""
#: preset/actions.go:170
#: preset/actions.go:154 preset/actions.go:159 preset/actions.go:167
msgid "Skipped module without name"
#: preset/actions.go:173 preset/actions.go:181 preset/actions.go:184
#: preset/actions.go:190 preset/actions.go:195 preset/actions.go:197
msgid "module"
msgstr ""
msgstr ""
#: preset/actions.go:178
#: preset/actions.go:154
#, c-format
msgid "Skipped module without name"
msgid "Module '%s': unsupported action"
msgstr ""
msgstr ""
#: preset/actions.go:1
90
#: preset/actions.go:1
59
#, c-format
#, c-format
msgid "Module '%s':
command '%s' failed
"
msgid "Module '%s':
unsupported action
"
msgstr ""
msgstr ""
#: preset/actions.go:1
98
#: preset/actions.go:1
67
#, c-format
#, c-format
msgid "Module '%s': co
mmand '%s' returned no data
"
msgid "Module '%s': co
ndition not met
"
msgstr ""
msgstr ""
#: preset/actions.go:
208
#: preset/actions.go:
173
#, c-format
#, c-format
msgid "Module '%s': binary '%s' not found"
msgid "Module '%s': binary '%s' not found"
msgstr ""
msgstr ""
#: preset/actions.go:
220 preset/actions.go:226
#: preset/actions.go:
181 preset/actions.go:184
#, c-format
#, c-format
msgid "Created empty module: %s"
msgid "Created empty module: %s"
msgstr ""
msgstr ""
#: preset/actions.go:
258
#: preset/actions.go:
195
msgid "Error (%s): %v"
msgid "Error (%s): %v"
msgstr ""
msgstr ""
#: preset/actions.go:286
#: preset/actions.go:208 preset/actions.go:214 preset/actions.go:222
msgid "Sync Hyprland layouts"
#: preset/actions.go:225 preset/actions.go:227
msgstr ""
msgid "layout"
#: preset/actions.go:295
msgid "Failed to get system layouts"
msgstr ""
msgstr ""
#: preset/actions.go:308
#: preset/actions.go:208
#, c-format
msgid "Sync Hyprland layouts"
msgid "XCB layout: %s"
msgstr ""
msgstr ""
#: preset/actions.go:312
#: preset/actions.go:214
#, c-format
msgid "Failed to get system layouts"
msgid "Hyprland layout: %s"
msgstr ""
msgstr ""
#: preset/actions.go:
319
#: preset/actions.go:
222
msgid "Failed to update kb_layout"
msgid "Failed to update kb_layout"
msgstr ""
msgstr ""
#: preset/actions.go:
3
25
#: preset/actions.go:
2
25
#, c-format
#, c-format
msgid "Layout updated: %s"
msgid "Layout updated: %s"
msgstr ""
msgstr ""
#: preset/actions.go:
330
#: preset/actions.go:
227
#, c-format
#, c-format
msgid "Layout already set: %s"
msgid "Layout already set: %s"
msgstr ""
msgstr ""
#: preset/actions.go:354
#: preset/actions.go:270
msgid "GRUB error: %v"
msgstr ""
#: preset/actions.go:359 system/grub-actions.go:86
msgid "GRUB_GFXMODE fixed"
msgstr ""
#: preset/actions.go:364 system/grub-actions.go:89
msgid "update-grub completed"
msgstr ""
#: preset/actions.go:392
#, c-format
#, c-format
msgid "
Creating profile: %s
"
msgid "
Profile %s not found
"
msgstr ""
msgstr ""
#: preset/actions.go:
394
#: preset/actions.go:
275
#, c-format
#, c-format
msgid "Profile %s unavailable"
msgid "Profile %s unavailable"
msgstr ""
msgstr ""
#: preset/actions.go:408 preset/actions.go:468
#: preset/actions.go:287 preset/actions.go:338
msgid "no available profiles"
#, c-format
msgid "Applying profile: %s"
msgstr ""
msgstr ""
#: preset/actions.go:
430
#: preset/actions.go:
321 preset/helpers.go:73
msgid "
P
rofiles"
msgid "
no available p
rofiles"
msgstr ""
msgstr ""
#: preset/actions.go:451
#: preset/commands.go:13
#, c-format
msgid "Show what would be created without making changes"
msgid "Profile %s not found"
msgstr ""
msgstr ""
#: preset/
actions.go:472
#: preset/
commands.go:18
msgid "
Creating all available profiles...
"
msgid "
Force overwrite existing files (backup to .bak)
"
msgstr ""
msgstr ""
#: preset/commands.go:
15
#: preset/commands.go:
26
msgid "Manage preset configuration profiles"
msgid "Manage preset configuration profiles"
msgstr ""
msgstr ""
#: preset/commands.go:
19
#: preset/commands.go:
30
msgid "Show information about preset profiles"
msgid "Show information about preset profiles"
msgstr ""
msgstr ""
#: preset/commands.go:
27
#: preset/commands.go:
38
msgid "Apply a profile"
msgid "Apply a profile"
msgstr ""
msgstr ""
#: preset/commands.go:31 preset/commands.go:45
#: preset/commands.go:45
msgid "Show what would be created without making changes"
msgstr ""
#: preset/commands.go:41
msgid "Apply all available profiles"
msgid "Apply all available profiles"
msgstr ""
msgstr ""
#: preset/tools.go:51
#: preset/helpers.go:93
#, c-format
msgid "Profiles"
msgid "Error: %s"
msgstr ""
#: preset/tools.go:85
msgid "Copying"
msgstr ""
#: preset/tools.go:86
msgid "Creating links"
msgstr ""
#: preset/tools.go:87
msgid "Updating"
msgstr ""
#: preset/tools.go:88
msgid "Configuring system"
msgstr ""
msgstr ""
#: preset/
tools.go:89
#: preset/
result.go:74
msgid "
Creating Hyprland variables
"
msgid "
done
"
msgstr ""
msgstr ""
#: preset/
tools.go:90
#: preset/
result.go:77
msgid "
Enabling Hyprland modules
"
msgid "
skipped
"
msgstr ""
msgstr ""
#: preset/tools.go:91
#: preset/result.go:80
msgid "Syncing Hyprland layout"
msgid "error"
msgstr ""
msgid_plural "errors"
msgstr[0] ""
msgstr[1] ""
#: repo/actions.go:31 repo/actions.go:38
#: repo/actions.go:31 repo/actions.go:38
msgid "Error fetching data"
msgid "Error fetching data"
...
...
preset/actions.go
View file @
72107231
...
@@ -2,44 +2,42 @@ package preset
...
@@ -2,44 +2,42 @@ package preset
import
(
import
(
"bytes"
"bytes"
"slices"
"ximperconf/config"
"ximperconf/hyprland"
"ximperconf/locale"
"ximperconf/system"
"ximperconf/ui"
"context"
"context"
"fmt"
"fmt"
"os"
"os"
"os/exec"
"os/exec"
"slices"
"sort"
"strings"
"strings"
"ximperconf/config"
"ximperconf/hyprland"
"ximperconf/locale"
"ximperconf/system"
"github.com/fatih/color"
"github.com/fatih/color"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v3"
)
)
var
(
var
validActions
=
[]
string
{
"enable"
,
"disable"
,
"remove"
}
validActions
=
[]
string
{
"enable"
,
"disable"
,
"remove"
}
)
// ===== Process functions =====
func
processCopies
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
func
processCopies
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
for
_
,
c
:=
range
prof
.
Copy
{
for
_
,
c
:=
range
prof
.
Copy
{
src
:=
expandPath
(
c
.
Src
,
""
)
src
:=
expandPath
(
c
.
Src
,
""
)
dest
:=
expandPath
(
c
.
Dest
,
""
)
dest
:=
expandPath
(
c
.
Dest
,
""
)
r
:=
copyIfMissing
(
src
,
dest
,
opts
)
status
,
msg
:=
execCopy
(
src
,
dest
,
opts
)
AppendOpResult
(
res
,
r
)
res
.
Add
(
locale
.
T
(
"copy"
),
msg
,
status
)
}
}
}
}
func
processLinks
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
func
processLinks
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
for
_
,
entry
:=
range
prof
.
Links
{
for
_
,
entry
:=
range
prof
.
Links
{
handle
:=
func
(
app
string
)
{
handle
:=
func
(
app
string
)
{
s
ys
:=
expandPath
(
entry
.
Sys
,
app
)
s
rc
:=
expandPath
(
entry
.
Src
,
app
)
user
:=
expandPath
(
entry
.
User
,
app
)
dest
:=
expandPath
(
entry
.
Dest
,
app
)
r
:=
createLinkIfMissing
(
sys
,
user
,
opts
)
status
,
msg
:=
execLink
(
src
,
dest
,
opts
)
AppendOpResult
(
res
,
r
)
res
.
Add
(
locale
.
T
(
"link"
),
msg
,
status
)
}
}
if
len
(
entry
.
Apps
)
>
0
{
if
len
(
entry
.
Apps
)
>
0
{
...
@@ -51,48 +49,34 @@ func processLinks(prof config.PresetProfile, opts opOptions, res *Result) {
...
@@ -51,48 +49,34 @@ func processLinks(prof config.PresetProfile, opts opOptions, res *Result) {
continue
continue
}
}
if
entry
.
App
!=
""
&&
!
commandExists
(
entry
.
App
)
{
continue
}
handle
(
""
)
handle
(
""
)
}
}
}
}
func
processRe
leaseRe
place
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
func
processReplace
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
sysVer
:=
getSystemVersion
()
sysVer
:=
getSystemVersion
()
for
_
,
rr
:=
range
prof
.
Re
leaseRe
place
{
for
_
,
rr
:=
range
prof
.
Replace
{
src
:=
expandPath
(
rr
.
Src
,
""
)
src
:=
expandPath
(
rr
.
Src
,
""
)
dest
:=
expandPath
(
rr
.
Dest
,
""
)
dest
:=
expandPath
(
rr
.
Dest
,
""
)
item
:=
handleReleas
eReplace
(
src
,
dest
,
sysVer
,
opts
)
status
,
msg
:=
handl
eReplace
(
src
,
dest
,
sysVer
,
opts
)
res
.
Replaced
=
append
(
res
.
Replaced
,
item
)
res
.
Add
(
locale
.
T
(
"replace"
),
msg
,
status
)
}
}
}
}
func
handleRe
leaseReplace
(
src
,
dest
,
sysVer
string
,
opts
opOptions
)
ui
.
TreeItem
{
func
handleRe
place
(
src
,
dest
,
sysVer
string
,
opts
opOptions
)
(
config
.
ItemStatus
,
string
)
{
if
_
,
err
:=
os
.
Stat
(
dest
);
os
.
IsNotExist
(
err
)
{
if
_
,
err
:=
os
.
Stat
(
dest
);
os
.
IsNotExist
(
err
)
{
return
ui
.
TreeItem
{
return
config
.
OpStatus
.
Skipped
,
fmt
.
Sprintf
(
locale
.
T
(
"Not found: '%s'"
),
dest
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Not found: '%s'"
),
dest
),
Status
:
config
.
OpStatus
.
Skipped
,
}
}
}
data
,
err
:=
os
.
ReadFile
(
dest
)
data
,
err
:=
os
.
ReadFile
(
dest
)
if
err
!=
nil
{
if
err
!=
nil
{
return
ui
.
TreeItem
{
return
config
.
OpStatus
.
Error
,
fmt
.
Sprintf
(
locale
.
T
(
"Failed to read %s: %v"
),
dest
,
err
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Failed to read %s: %v"
),
dest
,
err
),
Status
:
config
.
OpStatus
.
Error
,
}
}
}
content
:=
string
(
data
)
if
strings
.
Contains
(
string
(
data
),
"XIMPER_LOCK"
)
{
if
strings
.
Contains
(
content
,
"XIMPER_LOCK"
)
{
return
config
.
OpStatus
.
Skipped
,
fmt
.
Sprintf
(
locale
.
T
(
"Locked: %s"
),
dest
)
return
ui
.
TreeItem
{
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Locked: %s"
),
dest
),
Status
:
config
.
OpStatus
.
Skipped
,
}
}
}
fileVer
:=
getFileVersionTag
(
dest
)
fileVer
:=
getFileVersionTag
(
dest
)
...
@@ -100,341 +84,178 @@ func handleReleaseReplace(src, dest, sysVer string, opts opOptions) ui.TreeItem
...
@@ -100,341 +84,178 @@ func handleReleaseReplace(src, dest, sysVer string, opts opOptions) ui.TreeItem
fileVer
=
"0.9.3"
fileVer
=
"0.9.3"
}
}
if
fileVer
==
sysVer
{
if
!
opts
.
Force
&&
fileVer
==
sysVer
{
return
ui
.
TreeItem
{
return
config
.
OpStatus
.
Skipped
,
fmt
.
Sprintf
(
locale
.
T
(
"Up to date: '%s'"
),
dest
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Up to date: '%s'"
),
dest
),
Status
:
config
.
OpStatus
.
Skipped
,
}
}
}
if
opts
.
DryRun
{
if
opts
.
DryRun
{
return
ui
.
TreeItem
{
return
config
.
OpStatus
.
DryRun
,
fmt
.
Sprintf
(
"%s → %s"
,
src
,
dest
)
Name
:
fmt
.
Sprintf
(
"%s → %s"
,
src
,
dest
),
Status
:
config
.
OpStatus
.
DryRun
,
}
}
}
_
=
os
.
Rename
(
dest
,
dest
+
".
old
"
)
_
=
os
.
Rename
(
dest
,
dest
+
".
bak
"
)
if
err
:=
copyFile
(
src
,
dest
);
err
!=
nil
{
if
err
:=
copyFile
(
src
,
dest
);
err
!=
nil
{
return
ui
.
TreeItem
{
return
config
.
OpStatus
.
Error
,
fmt
.
Sprintf
(
locale
.
T
(
"Replace error %s: %v"
),
dest
,
err
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Replace error %s: %v"
),
dest
,
err
),
}
Status
:
config
.
OpStatus
.
Error
,
return
config
.
OpStatus
.
Done
,
fmt
.
Sprintf
(
"%s (%s → %s)"
,
dest
,
fileVer
,
sysVer
)
}
func
processSystemGrub
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
if
!
prof
.
System
.
Grub
.
FixResolution
{
return
}
}
autoUpdate
:=
prof
.
System
.
Grub
.
Update
if
opts
.
DryRun
{
res
.
Add
(
locale
.
T
(
"system"
),
"GRUB_GFXMODE"
,
config
.
OpStatus
.
DryRun
)
if
autoUpdate
{
res
.
Add
(
locale
.
T
(
"system"
),
"update-grub"
,
config
.
OpStatus
.
DryRun
)
}
return
}
}
return
ui
.
TreeItem
{
if
err
:=
system
.
SystemGrubFixResolution
(
autoUpdate
,
false
);
err
!=
nil
{
Name
:
fmt
.
Sprintf
(
"%s (%s → %s)"
,
dest
,
fileVer
,
sysVer
),
res
.
Add
(
locale
.
T
(
"system"
),
fmt
.
Sprintf
(
locale
.
T
(
"GRUB error: %v"
),
err
),
config
.
OpStatus
.
Error
)
Status
:
config
.
OpStatus
.
Done
,
return
}
res
.
Add
(
locale
.
T
(
"system"
),
locale
.
T
(
"GRUB_GFXMODE fixed"
),
config
.
OpStatus
.
Done
)
if
autoUpdate
{
res
.
Add
(
locale
.
T
(
"system"
),
locale
.
T
(
"update-grub completed"
),
config
.
OpStatus
.
Done
)
}
}
}
}
func
processHyprVars
(
manager
*
hyprland
.
HyprlandManager
,
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
func
processHyprVars
(
manager
*
hyprland
.
HyprlandManager
,
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
for
_
,
v
:=
range
prof
.
Hyprland
.
Vars
{
for
_
,
v
:=
range
prof
.
Hyprland
.
Vars
{
if
!
v
.
Force
{
if
!
v
.
Force
{
if
V
:=
manager
.
GetVar
(
v
.
Var
);
V
!=
""
{
if
existing
:=
manager
.
GetVar
(
v
.
Name
);
existing
!=
""
{
res
.
HyprVars
=
append
(
res
.
HyprVars
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"var"
),
fmt
.
Sprintf
(
locale
.
T
(
"Already exists: %s"
),
v
.
Name
),
config
.
OpStatus
.
Skipped
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Already exists: %s"
),
v
.
Var
),
Status
:
config
.
OpStatus
.
Skipped
,
})
continue
continue
}
}
}
}
if
opts
.
DryRun
{
if
opts
.
DryRun
{
res
.
HyprVars
=
append
(
res
.
HyprVars
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"var"
),
fmt
.
Sprintf
(
"%s = %s"
,
v
.
Name
,
v
.
Value
),
config
.
OpStatus
.
DryRun
)
Name
:
fmt
.
Sprintf
(
"%s = %s"
,
v
.
Var
,
v
.
Value
),
Status
:
config
.
OpStatus
.
DryRun
,
})
continue
continue
}
}
if
_
,
err
:=
manager
.
SetVar
(
v
.
Var
,
v
.
Value
);
err
!=
nil
{
if
_
,
err
:=
manager
.
SetVar
(
v
.
Name
,
v
.
Value
);
err
!=
nil
{
res
.
HyprVars
=
append
(
res
.
HyprVars
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"var"
),
fmt
.
Sprintf
(
locale
.
T
(
"Error setting %s: %v"
),
v
.
Name
,
err
),
config
.
OpStatus
.
Error
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Error setting %s: %v"
),
v
.
Var
,
err
),
Status
:
config
.
OpStatus
.
Error
,
})
}
else
{
}
else
{
res
.
HyprVars
=
append
(
res
.
HyprVars
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"var"
),
fmt
.
Sprintf
(
"%s = %s"
,
v
.
Name
,
v
.
Value
),
config
.
OpStatus
.
Done
)
Name
:
fmt
.
Sprintf
(
"%s = %s"
,
v
.
Var
,
v
.
Value
),
Status
:
config
.
OpStatus
.
Done
,
})
}
}
}
}
}
}
func
processHyprModules
(
manager
*
hyprland
.
HyprlandManager
,
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
func
processHyprModules
(
manager
*
hyprland
.
HyprlandManager
,
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
for
_
,
m
:=
range
prof
.
Hyprland
.
Modules
{
for
_
,
m
:=
range
prof
.
Hyprland
.
Modules
{
if
m
.
Name
==
""
{
if
m
.
Module
==
""
{
res
.
Add
(
locale
.
T
(
"module"
),
locale
.
T
(
"Skipped module without name"
),
config
.
OpStatus
.
Skipped
)
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
Name
:
locale
.
T
(
"Skipped module without name"
),
Status
:
config
.
OpStatus
.
Skipped
,
})
continue
continue
}
}
if
!
slices
.
Contains
(
validActions
,
m
.
Action
)
{
if
!
slices
.
Contains
(
validActions
,
m
.
Action
)
{
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"module"
),
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s': unsupported action"
),
m
.
Name
),
config
.
OpStatus
.
Skipped
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s': unsupported action"
),
m
.
Module
),
Status
:
config
.
OpStatus
.
Skipped
,
})
continue
continue
}
}
// if-exec
if
m
.
IfExec
!=
""
{
if
m
.
IfExec
!=
""
{
cmd
:=
exec
.
Command
(
"sh"
,
"-c"
,
m
.
IfExec
)
cmd
:=
exec
.
Command
(
"sh"
,
"-c"
,
m
.
IfExec
)
output
,
err
:=
cmd
.
Output
()
output
,
err
:=
cmd
.
Output
()
if
err
!=
nil
{
if
err
!=
nil
||
len
(
bytes
.
TrimSpace
(
output
))
==
0
{
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"module"
),
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s': condition not met"
),
m
.
Name
),
config
.
OpStatus
.
Skipped
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s': command '%s' failed"
),
m
.
Module
,
m
.
IfExec
),
Status
:
config
.
OpStatus
.
Skipped
,
})
continue
}
if
len
(
bytes
.
TrimSpace
(
output
))
==
0
{
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s': command '%s' returned no data"
),
m
.
Module
,
m
.
IfExec
),
Status
:
config
.
OpStatus
.
Skipped
,
})
continue
continue
}
}
}
}
// if-binary
if
m
.
IfBinary
!=
""
&&
!
commandExists
(
m
.
IfBinary
)
{
if
m
.
IfBinary
!=
""
&&
!
commandExists
(
m
.
IfBinary
)
{
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"module"
),
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s': binary '%s' not found"
),
m
.
Name
,
m
.
IfBinary
),
config
.
OpStatus
.
Skipped
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s': binary '%s' not found"
),
m
.
Module
,
m
.
IfBinary
),
Status
:
config
.
OpStatus
.
Skipped
,
})
continue
continue
}
}
if
m
.
Init
&&
m
.
User
&&
m
.
Action
==
"enable"
{
if
m
.
Init
&&
m
.
User
&&
m
.
Action
==
"enable"
{
modulefile
:=
manager
.
GetModuleFile
(
m
.
Module
,
m
.
User
)
modulefile
:=
manager
.
GetModuleFile
(
m
.
Name
,
m
.
User
)
if
_
,
err
:=
os
.
Stat
(
modulefile
);
os
.
IsNotExist
(
err
)
{
if
_
,
err
:=
os
.
Stat
(
modulefile
);
os
.
IsNotExist
(
err
)
{
if
opts
.
DryRun
{
if
opts
.
DryRun
{
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"module"
),
fmt
.
Sprintf
(
locale
.
T
(
"Created empty module: %s"
),
m
.
Name
),
config
.
OpStatus
.
DryRun
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Created empty module: %s"
),
m
.
Module
),
Status
:
config
.
OpStatus
.
DryRun
,
})
}
else
{
}
else
{
_
=
os
.
WriteFile
(
modulefile
,
[]
byte
(
""
),
0
o644
)
_
=
os
.
WriteFile
(
modulefile
,
[]
byte
(
""
),
0
o644
)
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"module"
),
fmt
.
Sprintf
(
locale
.
T
(
"Created empty module: %s"
),
m
.
Name
),
config
.
OpStatus
.
Done
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Created empty module: %s"
),
m
.
Module
),
Status
:
config
.
OpStatus
.
Done
,
})
}
}
}
}
}
}
// dry-run
if
opts
.
DryRun
{
if
opts
.
DryRun
{
var
msg
string
res
.
Add
(
locale
.
T
(
"module"
),
fmt
.
Sprintf
(
"%s: %s"
,
m
.
Name
,
m
.
Action
),
config
.
OpStatus
.
DryRun
)
switch
m
.
Action
{
case
"enable"
:
msg
=
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s' enabled"
),
m
.
Module
)
case
"disable"
:
msg
=
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s' disabled"
),
m
.
Module
)
case
"remove"
:
msg
=
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s' removed"
),
m
.
Module
)
}
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
Name
:
msg
,
Status
:
config
.
OpStatus
.
DryRun
,
})
continue
continue
}
}
if
_
,
err
:=
manager
.
SetModule
(
if
_
,
err
:=
manager
.
SetModule
(
m
.
Action
,
m
.
Name
,
m
.
User
,
m
.
NewOnly
);
err
!=
nil
{
m
.
Action
,
res
.
Add
(
locale
.
T
(
"module"
),
fmt
.
Sprintf
(
locale
.
T
(
"Error (%s): %v"
),
m
.
Name
,
err
),
config
.
OpStatus
.
Error
)
m
.
Module
,
m
.
User
,
m
.
NewOnly
,
);
err
!=
nil
{
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Error (%s): %v"
),
m
.
Module
,
err
),
Status
:
config
.
OpStatus
.
Error
,
})
}
else
{
}
else
{
var
msg
string
res
.
Add
(
locale
.
T
(
"module"
),
fmt
.
Sprintf
(
"%s: %s"
,
m
.
Name
,
m
.
Action
),
config
.
OpStatus
.
Done
)
switch
m
.
Action
{
case
"enable"
:
msg
=
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s' enabled"
),
m
.
Module
)
case
"disable"
:
msg
=
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s' disabled"
),
m
.
Module
)
case
"remove"
:
msg
=
fmt
.
Sprintf
(
locale
.
T
(
"Module '%s' removed"
),
m
.
Module
)
}
res
.
HyprModules
=
append
(
res
.
HyprModules
,
ui
.
TreeItem
{
Name
:
msg
,
Status
:
config
.
OpStatus
.
Done
,
})
}
}
}
}
}
}
func
processHyprLayoutSync
(
manager
*
hyprland
.
HyprlandManager
,
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
func
processHyprLayoutSync
(
manager
*
hyprland
.
HyprlandManager
,
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
if
!
prof
.
Hyprland
.
Option
.
SyncSystem
Layouts
{
if
!
prof
.
Hyprland
.
Sync
Layouts
{
return
return
}
}
if
opts
.
DryRun
{
if
opts
.
DryRun
{
res
.
SyncSystemLayouts
=
append
(
res
.
SyncSystemLayouts
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"layout"
),
locale
.
T
(
"Sync Hyprland layouts"
),
config
.
OpStatus
.
DryRun
)
Name
:
locale
.
T
(
"Sync Hyprland layouts"
),
Status
:
config
.
OpStatus
.
DryRun
,
})
return
return
}
}
sysLayouts
,
err
:=
hyprland
.
HyprlandGetKeyboardLayouts
()
sysLayouts
,
err
:=
hyprland
.
HyprlandGetKeyboardLayouts
()
if
err
!=
nil
{
if
err
!=
nil
{
res
.
SyncSystemLayouts
=
append
(
res
.
SyncSystemLayouts
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"layout"
),
locale
.
T
(
"Failed to get system layouts"
),
config
.
OpStatus
.
Error
)
Name
:
locale
.
T
(
"Failed to get system layouts"
),
Status
:
config
.
OpStatus
.
Error
,
})
return
return
}
}
hyprLayouts
:=
manager
.
GetVar
(
"kb_layout"
)
hyprLayouts
:=
manager
.
GetVar
(
"kb_layout"
)
if
hyprLayouts
==
""
{
if
hyprLayouts
==
""
{
hyprLayouts
=
"<empty>"
}
res
.
SyncSystemLayouts
=
append
(
res
.
SyncSystemLayouts
,
ui
.
TreeItem
{
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"XCB layout: %s"
),
sysLayouts
),
Status
:
config
.
OpStatus
.
Done
,
})
res
.
SyncSystemLayouts
=
append
(
res
.
SyncSystemLayouts
,
ui
.
TreeItem
{
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Hyprland layout: %s"
),
hyprLayouts
),
Status
:
config
.
OpStatus
.
Done
,
})
if
hyprLayouts
==
"<empty>"
{
if
_
,
err
:=
manager
.
SetVar
(
"kb_layout"
,
sysLayouts
);
err
!=
nil
{
if
_
,
err
:=
manager
.
SetVar
(
"kb_layout"
,
sysLayouts
);
err
!=
nil
{
res
.
SyncSystemLayouts
=
append
(
res
.
SyncSystemLayouts
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"layout"
),
locale
.
T
(
"Failed to update kb_layout"
),
config
.
OpStatus
.
Error
)
Name
:
locale
.
T
(
"Failed to update kb_layout"
),
Status
:
config
.
OpStatus
.
Error
,
})
return
return
}
}
res
.
SyncSystemLayouts
=
append
(
res
.
SyncSystemLayouts
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"layout"
),
fmt
.
Sprintf
(
locale
.
T
(
"Layout updated: %s"
),
sysLayouts
),
config
.
OpStatus
.
Done
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Layout updated: %s"
),
sysLayouts
),
Status
:
config
.
OpStatus
.
Done
,
})
}
else
{
}
else
{
res
.
SyncSystemLayouts
=
append
(
res
.
SyncSystemLayouts
,
ui
.
TreeItem
{
res
.
Add
(
locale
.
T
(
"layout"
),
fmt
.
Sprintf
(
locale
.
T
(
"Layout already set: %s"
),
hyprLayouts
),
config
.
OpStatus
.
Skipped
)
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"Layout already set: %s"
),
hyprLayouts
),
Status
:
config
.
OpStatus
.
Skipped
,
})
}
}
}
}
func
processSystemGrub
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
)
{
// ===== Orchestration =====
if
prof
.
System
.
Grub
.
FixResolution
{
autoUpdate
:=
prof
.
System
.
Grub
.
Update
if
opts
.
DryRun
{
res
.
System
=
append
(
res
.
System
,
ui
.
TreeItem
{
Name
:
"GRUB_GFXMODE"
,
Status
:
config
.
OpStatus
.
DryRun
,
})
if
autoUpdate
{
res
.
System
=
append
(
res
.
System
,
ui
.
TreeItem
{
Name
:
"update-grub"
,
Status
:
config
.
OpStatus
.
DryRun
,
})
}
}
else
{
err
:=
system
.
SystemGrubFixResolution
(
autoUpdate
,
false
)
if
err
!=
nil
{
res
.
System
=
append
(
res
.
System
,
ui
.
TreeItem
{
Name
:
fmt
.
Sprintf
(
locale
.
T
(
"GRUB error: %v"
),
err
),
Status
:
config
.
OpStatus
.
Error
,
})
}
else
{
res
.
System
=
append
(
res
.
System
,
ui
.
TreeItem
{
Name
:
locale
.
T
(
"GRUB_GFXMODE fixed"
),
Status
:
config
.
OpStatus
.
Done
,
})
if
autoUpdate
{
res
.
System
=
append
(
res
.
System
,
ui
.
TreeItem
{
Name
:
locale
.
T
(
"update-grub completed"
),
Status
:
config
.
OpStatus
.
Done
,
})
}
}
}
}
}
func
processProfile
(
prof
config
.
PresetProfile
,
dryRun
bool
,
res
*
Result
)
{
opts
:=
opOptions
{
DryRun
:
dryRun
}
func
processProfile
(
prof
config
.
PresetProfile
,
opts
opOptions
,
res
*
Result
,
manager
*
hyprland
.
HyprlandManager
)
{
processCopies
(
prof
,
opts
,
res
)
processCopies
(
prof
,
opts
,
res
)
processLinks
(
prof
,
opts
,
res
)
processLinks
(
prof
,
opts
,
res
)
processReleaseReplace
(
prof
,
opts
,
res
)
processReplace
(
prof
,
opts
,
res
)
if
config
.
Env
.
IsRoot
{
if
config
.
Env
.
IsRoot
{
processSystemGrub
(
prof
,
opts
,
res
)
processSystemGrub
(
prof
,
opts
,
res
)
}
}
manager
,
err
:=
hyprland
.
NewHyprlandManager
()
if
err
!=
nil
{
if
manager
!=
nil
{
return
}
processHyprVars
(
manager
,
prof
,
opts
,
res
)
processHyprVars
(
manager
,
prof
,
opts
,
res
)
processHyprModules
(
manager
,
prof
,
opts
,
res
)
processHyprModules
(
manager
,
prof
,
opts
,
res
)
processHyprLayoutSync
(
manager
,
prof
,
opts
,
res
)
processHyprLayoutSync
(
manager
,
prof
,
opts
,
res
)
}
func
createProfile
(
profileName
string
,
prof
config
.
PresetProfile
,
dryRun
bool
,
res
*
Result
)
{
color
.
Green
(
locale
.
T
(
"Creating profile: %s"
),
profileName
)
if
!
profileAvailable
(
prof
)
{
color
.
Red
(
locale
.
T
(
"Profile %s unavailable"
),
profileName
)
return
}
}
processProfile
(
prof
,
dryRun
,
res
)
}
}
func
ShowProfilesInfo
(
jsonFormat
bool
)
{
func
tryCreateManager
()
*
hyprland
.
HyprlandManager
{
profiles
:=
config
.
Env
.
Preset
.
Profiles
manager
,
err
:=
hyprland
.
NewHyprlandManager
()
if
err
!=
nil
{
if
len
(
profiles
)
==
0
{
return
nil
if
jsonFormat
{
ui
.
PrintJSON
([]
ui
.
JSONItem
{})
return
}
color
.
Red
(
locale
.
T
(
"no available profiles"
))
return
}
items
:=
make
([]
ui
.
TreeItem
,
0
,
len
(
profiles
))
for
name
,
profile
:=
range
profiles
{
status
:=
profileStatus
(
profile
)
desc
:=
profile
.
Description
items
=
append
(
items
,
ui
.
TreeItem
{
Name
:
name
,
Status
:
status
,
Description
:
desc
,
})
}
if
jsonFormat
{
ui
.
PrintJSON
(
ui
.
TreeItemsToJSON
(
items
))
return
}
}
return
manager
ui
.
RenderTree
(
ui
.
RenderTreeOptions
{
Title
:
locale
.
T
(
"Profiles"
),
Items
:
items
,
Style
:
ui
.
DefaultTreeStyle
,
Color
:
true
,
Sort
:
true
,
})
}
}
// ===== Command handlers =====
func
presetApplyCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
func
presetApplyCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
profileName
:=
cmd
.
Args
()
.
Get
(
0
)
profileName
:=
cmd
.
Args
()
.
Get
(
0
)
...
@@ -443,42 +264,84 @@ func presetApplyCommand(ctx context.Context, cmd *cli.Command) error {
...
@@ -443,42 +264,84 @@ func presetApplyCommand(ctx context.Context, cmd *cli.Command) error {
return
nil
return
nil
}
}
dryRun
:=
cmd
.
Bool
(
"dry-run"
)
profiles
:=
config
.
Env
.
Profiles
profiles
:=
config
.
Env
.
Preset
.
Profiles
prof
,
ok
:=
profiles
[
profileName
]
mainProf
,
ok
:=
profiles
[
profileName
]
if
!
ok
{
if
!
ok
{
color
.
Red
(
locale
.
T
(
"Profile %s not found"
),
profileName
)
color
.
Red
(
locale
.
T
(
"Profile %s not found"
),
profileName
)
return
nil
return
nil
}
}
if
!
profileAvailable
(
prof
)
{
color
.
Red
(
locale
.
T
(
"Profile %s unavailable"
),
profileName
)
return
nil
}
opts
:=
opOptions
{
DryRun
:
cmd
.
Bool
(
"dry-run"
),
Force
:
cmd
.
Bool
(
"force"
),
}
manager
:=
tryCreateManager
()
res
:=
&
Result
{}
res
:=
&
Result
{}
createProfile
(
profileName
,
mainProf
,
dryRun
,
res
)
renderPresetResult
(
res
)
color
.
Green
(
locale
.
T
(
"Applying profile: %s"
),
profileName
)
processProfile
(
prof
,
opts
,
res
,
manager
)
res
.
Render
()
if
manager
!=
nil
&&
manager
.
Changed
&&
!
opts
.
DryRun
{
manager
.
Save
()
}
return
nil
return
nil
}
}
func
presetApplyAllCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
type
namedProfile
struct
{
dryRun
:=
cmd
.
Bool
(
"dry-run"
)
Name
string
Profile
config
.
PresetProfile
}
func
sortedProfiles
(
profiles
map
[
string
]
config
.
PresetProfile
)
[]
namedProfile
{
sorted
:=
make
([]
namedProfile
,
0
,
len
(
profiles
))
for
name
,
prof
:=
range
profiles
{
sorted
=
append
(
sorted
,
namedProfile
{
Name
:
name
,
Profile
:
prof
})
}
sort
.
Slice
(
sorted
,
func
(
i
,
j
int
)
bool
{
if
sorted
[
i
]
.
Profile
.
Priority
!=
sorted
[
j
]
.
Profile
.
Priority
{
return
sorted
[
i
]
.
Profile
.
Priority
<
sorted
[
j
]
.
Profile
.
Priority
}
return
sorted
[
i
]
.
Name
<
sorted
[
j
]
.
Name
})
return
sorted
}
profiles
:=
config
.
Env
.
Preset
.
Profiles
func
presetApplyAllCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
profiles
:=
config
.
Env
.
Profiles
if
len
(
profiles
)
==
0
{
if
len
(
profiles
)
==
0
{
color
.
Red
(
locale
.
T
(
"no available profiles"
))
color
.
Red
(
locale
.
T
(
"no available profiles"
))
return
nil
return
nil
}
}
color
.
Cyan
(
locale
.
T
(
"Creating all available profiles..."
)
+
"
\n
"
)
opts
:=
opOptions
{
DryRun
:
cmd
.
Bool
(
"dry-run"
),
Force
:
cmd
.
Bool
(
"force"
),
}
for
name
,
prof
:=
range
profiles
{
manager
:=
tryCreateManager
()
if
!
profileAvailable
(
prof
)
{
for
_
,
np
:=
range
sortedProfiles
(
profiles
)
{
if
!
profileAvailable
(
np
.
Profile
)
{
continue
continue
}
}
res
:=
&
Result
{}
res
:=
&
Result
{}
createProfile
(
name
,
prof
,
dryRun
,
res
)
color
.
Green
(
locale
.
T
(
"Applying profile: %s"
),
np
.
Name
)
renderPresetResult
(
res
)
processProfile
(
np
.
Profile
,
opts
,
res
,
manager
)
res
.
Render
()
}
if
manager
!=
nil
&&
manager
.
Changed
&&
!
opts
.
DryRun
{
manager
.
Save
()
}
}
return
nil
return
nil
...
...
preset/commands.go
View file @
72107231
package
preset
package
preset
import
(
import
(
"context"
"fmt"
"ximperconf/config"
"ximperconf/config"
"ximperconf/locale"
"ximperconf/locale"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v3"
)
)
var
presetFlags
=
[]
cli
.
Flag
{
&
cli
.
BoolFlag
{
Name
:
"dry-run"
,
Usage
:
locale
.
T
(
"Show what would be created without making changes"
),
Aliases
:
[]
string
{
"d"
},
},
&
cli
.
BoolFlag
{
Name
:
"force"
,
Usage
:
locale
.
T
(
"Force overwrite existing files (backup to .bak)"
),
Aliases
:
[]
string
{
"f"
},
},
}
func
CommandList
()
*
cli
.
Command
{
func
CommandList
()
*
cli
.
Command
{
return
&
cli
.
Command
{
return
&
cli
.
Command
{
Name
:
"preset"
,
Name
:
"preset"
,
...
@@ -25,44 +36,16 @@ func CommandList() *cli.Command {
...
@@ -25,44 +36,16 @@ func CommandList() *cli.Command {
{
{
Name
:
"apply"
,
Name
:
"apply"
,
Usage
:
locale
.
T
(
"Apply a profile"
),
Usage
:
locale
.
T
(
"Apply a profile"
),
Flags
:
[]
cli
.
Flag
{
Flags
:
presetFlags
,
&
cli
.
BoolFlag
{
Name
:
"dry-run"
,
Usage
:
locale
.
T
(
"Show what would be created without making changes"
),
Aliases
:
[]
string
{
"d"
},
Value
:
false
,
},
},
Action
:
presetApplyCommand
,
Action
:
presetApplyCommand
,
ShellComplete
:
ShellCompleteProfiles
,
ShellComplete
:
ShellCompleteProfiles
,
},
},
{
{
Name
:
"apply-all"
,
Name
:
"apply-all"
,
Usage
:
locale
.
T
(
"Apply all available profiles"
),
Usage
:
locale
.
T
(
"Apply all available profiles"
),
Flags
:
[]
cli
.
Flag
{
Flags
:
presetFlags
,
&
cli
.
BoolFlag
{
Name
:
"dry-run"
,
Usage
:
locale
.
T
(
"Show what would be created without making changes"
),
Aliases
:
[]
string
{
"d"
},
Value
:
false
,
},
},
Action
:
presetApplyAllCommand
,
Action
:
presetApplyAllCommand
,
},
},
},
},
}
}
}
}
func
ShellCompleteProfiles
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
{
if
cmd
.
NArg
()
>
0
{
return
}
profiles
:=
config
.
Env
.
Preset
.
Profiles
for
profileName
,
profile
:=
range
profiles
{
if
profileAvailable
(
profile
)
{
fmt
.
Println
(
profileName
)
}
}
}
preset/files.go
→
preset/file
op
s.go
View file @
72107231
...
@@ -2,67 +2,35 @@ package preset
...
@@ -2,67 +2,35 @@ package preset
import
(
import
(
"os"
"os"
"os/exec"
"path/filepath"
"path/filepath"
"strings"
"strings"
"ximperconf/config"
"ximperconf/config"
)
)
type
opKind
string
const
(
OpCopy
opKind
=
"copy"
OpLink
opKind
=
"link"
OpReplace
opKind
=
"replace"
)
type
opOptions
struct
{
type
opOptions
struct
{
DryRun
bool
DryRun
bool
Force
bool
Force
bool
}
}
type
opResult
struct
{
func
execCopy
(
src
,
dest
string
,
opts
opOptions
)
(
config
.
ItemStatus
,
string
)
{
Kind
opKind
Status
config
.
ItemStatus
Source
string
Target
string
Reason
string
}
func
commandExists
(
name
string
)
bool
{
_
,
err
:=
exec
.
LookPath
(
name
)
return
err
==
nil
}
// ===== Copy =====
func
copyIfMissing
(
src
,
dest
string
,
opts
opOptions
)
opResult
{
info
,
err
:=
os
.
Stat
(
src
)
info
,
err
:=
os
.
Stat
(
src
)
if
err
!=
nil
{
if
err
!=
nil
{
return
opResult
{
return
config
.
OpStatus
.
Error
,
err
.
Error
()
Kind
:
OpCopy
,
Status
:
config
.
OpStatus
.
Error
,
Source
:
src
,
Target
:
dest
,
Reason
:
err
.
Error
(),
}
}
}
exists
:=
false
if
_
,
err
:=
os
.
Stat
(
dest
);
err
==
nil
{
if
_
,
err
:=
os
.
Stat
(
dest
);
err
==
nil
{
return
opResult
{
if
!
opts
.
Force
{
Kind
:
OpCopy
,
return
config
.
OpStatus
.
Skipped
,
dest
+
" (exists)"
Status
:
config
.
OpStatus
.
Skipped
,
}
Target
:
dest
,
exists
=
true
Reason
:
"already exists"
,
if
!
opts
.
DryRun
{
_
=
os
.
Rename
(
dest
,
dest
+
".bak"
)
}
}
}
}
if
opts
.
DryRun
{
if
opts
.
DryRun
{
return
opResult
{
return
config
.
OpStatus
.
DryRun
,
src
+
" → "
+
dest
Kind
:
OpCopy
,
Status
:
config
.
OpStatus
.
DryRun
,
Source
:
src
,
Target
:
dest
,
}
}
}
if
info
.
IsDir
()
{
if
info
.
IsDir
()
{
...
@@ -72,21 +40,49 @@ func copyIfMissing(src, dest string, opts opOptions) opResult {
...
@@ -72,21 +40,49 @@ func copyIfMissing(src, dest string, opts opOptions) opResult {
}
}
if
err
!=
nil
{
if
err
!=
nil
{
return
opResult
{
return
config
.
OpStatus
.
Error
,
err
.
Error
()
Kind
:
OpCopy
,
Status
:
config
.
OpStatus
.
Error
,
Source
:
src
,
Target
:
dest
,
Reason
:
err
.
Error
(),
}
}
msg
:=
src
+
" → "
+
dest
if
exists
{
msg
+=
" (overwritten)"
}
}
return
config
.
OpStatus
.
Done
,
msg
}
return
opResult
{
func
execLink
(
src
,
dest
string
,
opts
opOptions
)
(
config
.
ItemStatus
,
string
)
{
Kind
:
OpCopy
,
if
_
,
err
:=
os
.
Stat
(
src
);
os
.
IsNotExist
(
err
)
{
Status
:
config
.
OpStatus
.
Done
,
return
config
.
OpStatus
.
Skipped
,
src
+
" → "
+
dest
+
" (source missing)"
Source
:
src
,
}
Target
:
dest
,
exists
:=
false
if
_
,
err
:=
os
.
Lstat
(
dest
);
err
==
nil
{
if
!
opts
.
Force
{
return
config
.
OpStatus
.
Skipped
,
dest
+
" (exists)"
}
exists
=
true
if
!
opts
.
DryRun
{
_
=
os
.
Rename
(
dest
,
dest
+
".bak"
)
}
}
if
opts
.
DryRun
{
return
config
.
OpStatus
.
DryRun
,
src
+
" → "
+
dest
}
if
err
:=
os
.
MkdirAll
(
filepath
.
Dir
(
dest
),
0755
);
err
!=
nil
{
return
config
.
OpStatus
.
Error
,
err
.
Error
()
}
if
err
:=
os
.
Symlink
(
src
,
dest
);
err
!=
nil
{
return
config
.
OpStatus
.
Error
,
err
.
Error
()
}
}
msg
:=
src
+
" → "
+
dest
if
exists
{
msg
+=
" (overwritten)"
}
return
config
.
OpStatus
.
Done
,
msg
}
}
func
copyFile
(
src
,
dest
string
)
error
{
func
copyFile
(
src
,
dest
string
)
error
{
...
@@ -121,60 +117,8 @@ func copyDir(src, dest string) error {
...
@@ -121,60 +117,8 @@ func copyDir(src, dest string) error {
})
})
}
}
// ===== Link =====
func
createLinkIfMissing
(
src
,
dest
string
,
opts
opOptions
)
opResult
{
if
_
,
err
:=
os
.
Stat
(
src
);
os
.
IsNotExist
(
err
)
{
return
opResult
{
Kind
:
OpLink
,
Status
:
config
.
OpStatus
.
Skipped
,
Target
:
dest
,
Reason
:
"source missing"
,
}
}
if
_
,
err
:=
os
.
Lstat
(
dest
);
err
==
nil
{
return
opResult
{
Kind
:
OpLink
,
Status
:
config
.
OpStatus
.
Skipped
,
Target
:
dest
,
Reason
:
"already exists"
,
}
}
if
opts
.
DryRun
{
return
opResult
{
Kind
:
OpLink
,
Status
:
config
.
OpStatus
.
DryRun
,
Source
:
src
,
Target
:
dest
,
}
}
if
err
:=
os
.
MkdirAll
(
filepath
.
Dir
(
dest
),
0755
);
err
!=
nil
{
return
opResult
{
Kind
:
OpLink
,
Status
:
config
.
OpStatus
.
Error
,
Reason
:
err
.
Error
(),
}
}
if
err
:=
os
.
Symlink
(
src
,
dest
);
err
!=
nil
{
return
opResult
{
Kind
:
OpLink
,
Status
:
config
.
OpStatus
.
Error
,
Reason
:
err
.
Error
(),
}
}
return
opResult
{
Kind
:
OpLink
,
Status
:
config
.
OpStatus
.
Done
,
Source
:
src
,
Target
:
dest
,
}
}
// ===== Versions =====
// ===== Versions =====
func
getSystemVersion
()
string
{
func
getSystemVersion
()
string
{
data
,
err
:=
os
.
ReadFile
(
"/etc/os-release"
)
data
,
err
:=
os
.
ReadFile
(
"/etc/os-release"
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
preset/
tool
s.go
→
preset/
helper
s.go
View file @
72107231
package
preset
package
preset
import
(
import
(
"context"
"fmt"
"fmt"
"os"
"os"
"os/exec"
"os/exec"
"path/filepath"
"path/filepath"
"strings"
"strings"
"ximperconf/config"
"ximperconf/config"
"ximperconf/locale"
"ximperconf/locale"
"ximperconf/ui"
"ximperconf/ui"
"github.com/urfave/cli/v3"
)
)
func
profileAvailable
(
p
config
.
PresetProfile
)
bool
{
func
profileAvailable
(
p
config
.
PresetProfile
)
bool
{
allowed
:=
false
if
p
.
Binary
!=
""
{
if
_
,
err
:=
exec
.
LookPath
(
p
.
Binary
);
err
!=
nil
{
if
p
.
Binary
==
""
{
return
false
allowed
=
true
}
}
else
if
_
,
err
:=
exec
.
LookPath
(
p
.
Binary
);
err
==
nil
{
allowed
=
true
}
}
if
p
.
Root
!=
config
.
Env
.
IsRoot
{
if
p
.
Root
!=
config
.
Env
.
IsRoot
{
allowed
=
false
return
false
}
}
return
allowed
return
true
}
}
func
profileStatus
(
p
config
.
PresetProfile
)
config
.
ItemStatus
{
func
profileStatus
(
p
config
.
PresetProfile
)
config
.
ItemStatus
{
...
@@ -35,28 +35,9 @@ func profileStatus(p config.PresetProfile) config.ItemStatus {
...
@@ -35,28 +35,9 @@ func profileStatus(p config.PresetProfile) config.ItemStatus {
return
config
.
ProfileStatus
.
Unavailable
return
config
.
ProfileStatus
.
Unavailable
}
}
func
AppendOpResult
(
res
*
Result
,
r
opResult
)
{
func
commandExists
(
name
string
)
bool
{
item
:=
ui
.
TreeItem
{
_
,
err
:=
exec
.
LookPath
(
name
)
Status
:
r
.
Status
,
return
err
==
nil
}
switch
{
case
r
.
Status
.
IsEqual
(
config
.
OpStatus
.
Skipped
)
:
item
.
Name
=
fmt
.
Sprintf
(
locale
.
T
(
"Already exists: %s"
),
r
.
Target
)
case
r
.
Status
.
IsEqual
(
config
.
OpStatus
.
DryRun
)
:
item
.
Name
=
fmt
.
Sprintf
(
"%s → %s"
,
r
.
Source
,
r
.
Target
)
case
r
.
Status
.
IsEqual
(
config
.
OpStatus
.
Done
)
:
item
.
Name
=
fmt
.
Sprintf
(
"%s → %s"
,
r
.
Source
,
r
.
Target
)
case
r
.
Status
.
IsEqual
(
config
.
OpStatus
.
Error
)
:
item
.
Name
=
fmt
.
Sprintf
(
locale
.
T
(
"Error: %s"
),
r
.
Reason
)
}
switch
r
.
Kind
{
case
OpCopy
:
res
.
Copies
=
append
(
res
.
Copies
,
item
)
case
OpLink
:
res
.
Links
=
append
(
res
.
Links
,
item
)
}
}
}
func
expandPath
(
path
,
name
string
)
string
{
func
expandPath
(
path
,
name
string
)
string
{
...
@@ -81,12 +62,50 @@ func expandPath(path, name string) string {
...
@@ -81,12 +62,50 @@ func expandPath(path, name string) string {
return
path
return
path
}
}
func
renderPresetResult
(
res
*
Result
)
{
func
ShowProfilesInfo
(
jsonFormat
bool
)
{
ui
.
RenderTreeItems
(
locale
.
T
(
"Copying"
),
res
.
Copies
)
profiles
:=
config
.
Env
.
Profiles
ui
.
RenderTreeItems
(
locale
.
T
(
"Creating links"
),
res
.
Links
)
ui
.
RenderTreeItems
(
locale
.
T
(
"Updating"
),
res
.
Replaced
)
if
len
(
profiles
)
==
0
{
ui
.
RenderTreeItems
(
locale
.
T
(
"Configuring system"
),
res
.
System
)
if
jsonFormat
{
ui
.
RenderTreeItems
(
locale
.
T
(
"Creating Hyprland variables"
),
res
.
HyprVars
)
ui
.
PrintJSON
([]
ui
.
JSONItem
{})
ui
.
RenderTreeItems
(
locale
.
T
(
"Enabling Hyprland modules"
),
res
.
HyprModules
)
return
ui
.
RenderTreeItems
(
locale
.
T
(
"Syncing Hyprland layout"
),
res
.
SyncSystemLayouts
)
}
fmt
.
Println
(
config
.
OpStatus
.
Error
.
Color
(
locale
.
T
(
"no available profiles"
)))
return
}
items
:=
make
([]
ui
.
TreeItem
,
0
,
len
(
profiles
))
for
name
,
profile
:=
range
profiles
{
items
=
append
(
items
,
ui
.
TreeItem
{
Name
:
name
,
Status
:
profileStatus
(
profile
),
Description
:
profile
.
Description
,
})
}
if
jsonFormat
{
ui
.
PrintJSON
(
ui
.
TreeItemsToJSON
(
items
))
return
}
ui
.
RenderTree
(
ui
.
RenderTreeOptions
{
Title
:
locale
.
T
(
"Profiles"
),
Items
:
items
,
Style
:
ui
.
DefaultTreeStyle
,
Color
:
true
,
Sort
:
true
,
})
}
func
ShellCompleteProfiles
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
{
if
cmd
.
NArg
()
>
0
{
return
}
for
name
,
profile
:=
range
config
.
Env
.
Profiles
{
if
profileAvailable
(
profile
)
{
fmt
.
Println
(
name
)
}
}
}
}
preset/result.go
View file @
72107231
package
preset
package
preset
import
"ximperconf/ui"
import
(
"fmt"
"ximperconf/config"
"ximperconf/locale"
)
type
LogEntry
struct
{
Category
string
Name
string
Status
config
.
ItemStatus
}
type
Result
struct
{
type
Result
struct
{
Copies
[]
ui
.
TreeItem
entries
[]
LogEntry
Links
[]
ui
.
TreeItem
}
Replaced
[]
ui
.
TreeItem
System
[]
ui
.
TreeItem
func
(
r
*
Result
)
Add
(
category
,
name
string
,
status
config
.
ItemStatus
)
{
HyprVars
[]
ui
.
TreeItem
r
.
entries
=
append
(
r
.
entries
,
LogEntry
{
HyprModules
[]
ui
.
TreeItem
Category
:
category
,
SyncSystemLayouts
[]
ui
.
TreeItem
Name
:
name
,
Status
:
status
,
})
}
func
(
r
*
Result
)
Render
()
{
if
len
(
r
.
entries
)
==
0
{
return
}
maxCat
:=
0
for
_
,
e
:=
range
r
.
entries
{
if
len
([]
rune
(
e
.
Category
))
>
maxCat
{
maxCat
=
len
([]
rune
(
e
.
Category
))
}
}
for
_
,
e
:=
range
r
.
entries
{
symbol
:=
e
.
Status
.
Symbol
cat
:=
fmt
.
Sprintf
(
"%-*s"
,
maxCat
,
e
.
Category
)
if
e
.
Status
.
Color
!=
nil
{
symbol
=
e
.
Status
.
Color
(
symbol
)
cat
=
e
.
Status
.
Color
(
cat
)
}
fmt
.
Printf
(
" %s %s %s
\n
"
,
symbol
,
cat
,
e
.
Name
)
}
summary
:=
r
.
Summary
()
if
summary
!=
""
{
fmt
.
Println
()
fmt
.
Printf
(
" %s
\n
"
,
summary
)
}
}
func
(
r
*
Result
)
Summary
()
string
{
var
done
,
skipped
,
errors
int
for
_
,
e
:=
range
r
.
entries
{
switch
{
case
e
.
Status
.
IsEqual
(
config
.
OpStatus
.
Done
)
:
done
++
case
e
.
Status
.
IsEqual
(
config
.
OpStatus
.
Skipped
)
:
skipped
++
case
e
.
Status
.
IsEqual
(
config
.
OpStatus
.
Error
)
:
errors
++
case
e
.
Status
.
IsEqual
(
config
.
OpStatus
.
DryRun
)
:
done
++
}
}
parts
:=
[]
string
{}
if
done
>
0
{
parts
=
append
(
parts
,
fmt
.
Sprintf
(
"%d %s"
,
done
,
locale
.
T
(
"done"
)))
}
if
skipped
>
0
{
parts
=
append
(
parts
,
fmt
.
Sprintf
(
"%d %s"
,
skipped
,
locale
.
T
(
"skipped"
)))
}
if
errors
>
0
{
parts
=
append
(
parts
,
fmt
.
Sprintf
(
"%d %s"
,
errors
,
locale
.
TN
(
"error"
,
"errors"
,
errors
)))
}
if
len
(
parts
)
==
0
{
return
""
}
result
:=
parts
[
0
]
for
i
:=
1
;
i
<
len
(
parts
);
i
++
{
result
+=
", "
+
parts
[
i
]
}
return
result
}
}
ui/rendertreelines.go
deleted
100644 → 0
View file @
5b29e43c
package
ui
import
(
"github.com/fatih/color"
)
func
RenderTreeLines
(
title
string
,
lines
[]
string
)
{
if
len
(
lines
)
==
0
{
return
}
color
.
Blue
(
"%s"
,
title
)
items
:=
make
([]
TreeItem
,
len
(
lines
))
for
i
,
line
:=
range
lines
{
items
[
i
]
=
TreeItem
{
Name
:
line
,
}
}
RenderTree
(
RenderTreeOptions
{
Items
:
items
,
Style
:
DefaultTreeStyle
,
Color
:
false
,
})
}
func
RenderTreeItems
(
title
string
,
items
[]
TreeItem
)
{
if
len
(
items
)
==
0
{
return
}
color
.
Blue
(
"%s"
,
title
)
RenderTree
(
RenderTreeOptions
{
Items
:
items
,
Style
:
DefaultTreeStyle
,
Color
:
true
,
})
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment