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
f65678f8
Verified
Commit
f65678f8
authored
Aug 24, 2025
by
Kirill Unitsaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add hyprland module subcommands
parent
86e75277
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
280 additions
and
5 deletions
+280
-5
config.go
config/config.go
+18
-2
go.mod
go.mod
+10
-1
go.sum
go.sum
+11
-0
actions.go
hyprland/actions.go
+198
-2
commands.go
hyprland/commands.go
+43
-0
No files found.
config/config.go
View file @
f65678f8
...
...
@@ -6,7 +6,9 @@ import (
)
type
HyprEnv
struct
{
Config
string
Config
string
SystemModulesDir
string
UserModulesDir
string
}
type
Environment
struct
{
...
...
@@ -28,7 +30,21 @@ func InitConfig() error {
home
,
_
:=
os
.
UserHomeDir
()
if
Env
.
Hyprland
!=
nil
{
confPath
:=
filepath
.
Join
(
home
,
".config"
,
"hypr"
,
"hyprland.conf"
)
userModulesPath
:=
filepath
.
Join
(
home
,
".config"
,
"hypr"
)
systemModulesPath
:=
"/etc/ximperdistro/hyprland/hypr"
confPath
:=
filepath
.
Join
(
userModulesPath
,
"hyprland.conf"
)
if
_
,
err
:=
os
.
Stat
(
userModulesPath
);
os
.
IsNotExist
(
err
)
{
_
=
os
.
MkdirAll
(
userModulesPath
,
0755
)
}
Env
.
Hyprland
.
UserModulesDir
=
userModulesPath
if
_
,
err
:=
os
.
Stat
(
systemModulesPath
);
os
.
IsNotExist
(
err
)
{
Env
.
Hyprland
.
SystemModulesDir
=
""
}
else
{
Env
.
Hyprland
.
SystemModulesDir
=
systemModulesPath
}
if
_
,
err
:=
os
.
Stat
(
confPath
);
err
==
nil
{
Env
.
Hyprland
.
Config
=
confPath
}
else
{
...
...
go.mod
View file @
f65678f8
...
...
@@ -2,4 +2,13 @@ module ximperconf
go 1.25.0
require github.com/urfave/cli/v3 v3.4.1
require (
github.com/fatih/color v1.18.0
github.com/urfave/cli/v3 v3.4.1
)
require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
golang.org/x/sys v0.25.0 // indirect
)
go.sum
View file @
f65678f8
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v3 v3.4.1 h1:1M9UOCy5bLmGnuu1yn3t3CB4rG79Rtoxuv1sPhnm6qM=
github.com/urfave/cli/v3 v3.4.1/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
hyprland/actions.go
View file @
f65678f8
package
hyprland
import
(
"context"
"fmt"
"ximperconf/config"
"bufio"
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"github.com/fatih/color"
"github.com/urfave/cli/v3"
)
var
(
HomeDir
,
_
=
os
.
UserHomeDir
()
)
func
CheckHyprland
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
h
:=
config
.
Env
.
Hyprland
if
h
==
nil
||
h
.
Config
==
""
{
...
...
@@ -39,3 +48,190 @@ func CheckHyprland(ctx context.Context, cmd *cli.Command) error {
fmt
.
Println
(
strings
.
Join
(
result
,
"
\n
"
))
return
nil
}
func
hyprlandGetModuleFile
(
module
string
,
user
bool
)
string
{
if
user
{
return
filepath
.
Join
(
config
.
Env
.
Hyprland
.
UserModulesDir
,
module
+
".conf"
)
}
return
filepath
.
Join
(
config
.
Env
.
Hyprland
.
SystemModulesDir
,
module
+
".conf"
)
}
func
fileExists
(
path
string
)
bool
{
_
,
err
:=
os
.
Stat
(
path
)
return
err
==
nil
}
func
hyprlandModuleStatus
(
module
string
,
user
bool
)
string
{
sysFile
:=
hyprlandGetModuleFile
(
module
,
user
)
lineFull
:=
"source = "
+
sysFile
lineTilde
:=
"source = ~"
+
strings
.
TrimPrefix
(
sysFile
,
HomeDir
)
if
!
fileExists
(
sysFile
)
{
fmt
.
Printf
(
"Модуль '%s' не найден: %s"
,
module
,
sysFile
)
os
.
Exit
(
1
)
return
""
}
if
!
fileExists
(
config
.
Env
.
Hyprland
.
Config
)
{
return
"disabled"
}
f
,
err
:=
os
.
Open
(
config
.
Env
.
Hyprland
.
Config
)
if
err
!=
nil
{
return
"disabled"
}
defer
f
.
Close
()
reFull
:=
regexp
.
MustCompile
(
`^\s*`
+
regexp
.
QuoteMeta
(
lineFull
)
+
`(?:\s|$)`
)
reTilde
:=
regexp
.
MustCompile
(
`^\s*`
+
regexp
.
QuoteMeta
(
lineTilde
)
+
`(?:\s|$)`
)
sc
:=
bufio
.
NewScanner
(
f
)
for
sc
.
Scan
()
{
line
:=
sc
.
Text
()
if
reFull
.
MatchString
(
line
)
||
reTilde
.
MatchString
(
line
)
{
return
"enabled"
}
}
return
"disabled"
}
func
HyprlandModuleStatusCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
status
:=
hyprlandModuleStatus
(
cmd
.
Args
()
.
Get
(
0
),
cmd
.
Bool
(
"user"
))
fmt
.
Println
(
status
)
return
nil
}
func
hyprlandSetModule
(
action
string
,
module
string
,
user
bool
)
{
sysFile
:=
hyprlandGetModuleFile
(
module
,
user
)
lineFull
:=
"source = "
+
sysFile
lineTilde
:=
"source = ~"
+
strings
.
TrimPrefix
(
sysFile
,
HomeDir
)
if
!
fileExists
(
sysFile
)
{
fmt
.
Printf
(
"Модуль '%s' не найден: %s"
,
module
,
sysFile
)
return
}
data
,
_
:=
os
.
ReadFile
(
config
.
Env
.
Hyprland
.
Config
)
lines
:=
strings
.
Split
(
string
(
data
),
"
\n
"
)
changed
:=
false
switch
action
{
case
"enable"
:
for
i
,
l
:=
range
lines
{
if
strings
.
TrimSpace
(
l
)
==
lineFull
||
strings
.
TrimSpace
(
l
)
==
lineTilde
{
fmt
.
Printf
(
"Модуль '%s' уже включён"
,
module
)
return
}
re
:=
regexp
.
MustCompile
(
`^\s*#\s*`
+
regexp
.
QuoteMeta
(
lineFull
)
+
`$`
)
if
re
.
MatchString
(
l
)
{
lines
[
i
]
=
lineFull
changed
=
true
}
re
=
regexp
.
MustCompile
(
`^\s*#\s*`
+
regexp
.
QuoteMeta
(
lineTilde
)
+
`$`
)
if
re
.
MatchString
(
l
)
{
lines
[
i
]
=
lineFull
changed
=
true
}
}
if
!
changed
{
lines
=
append
(
lines
,
lineTilde
)
}
color
.
Green
(
"Модуль '%s' включён"
,
module
)
case
"disable"
:
for
i
,
l
:=
range
lines
{
reFull
:=
regexp
.
MustCompile
(
`^\s*#\s*`
+
regexp
.
QuoteMeta
(
lineFull
)
+
`$`
)
reTilde
:=
regexp
.
MustCompile
(
`^\s*#\s*`
+
regexp
.
QuoteMeta
(
lineTilde
)
+
`$`
)
if
reFull
.
MatchString
(
l
)
||
reTilde
.
MatchString
(
l
)
{
color
.
Yellow
(
"Модуль '%s' уже отключён"
,
module
)
return
}
if
strings
.
TrimSpace
(
l
)
==
lineFull
||
strings
.
TrimSpace
(
l
)
==
lineTilde
{
lines
[
i
]
=
"# "
+
lineFull
changed
=
true
}
}
if
!
changed
{
color
.
Red
(
"Модуль '%s' не найден в конфигурации"
,
module
)
return
}
color
.
Yellow
(
"Модуль '%s' отключён"
,
module
)
}
_
=
os
.
WriteFile
(
config
.
Env
.
Hyprland
.
Config
,
[]
byte
(
strings
.
Join
(
lines
,
"
\n
"
)),
0644
)
}
func
HyprlandModuleEnableCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
hyprlandSetModule
(
"enable"
,
cmd
.
Args
()
.
Get
(
0
),
cmd
.
Bool
(
"user"
))
return
nil
}
func
HyprlandModuleDisableCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
hyprlandSetModule
(
"disable"
,
cmd
.
Args
()
.
Get
(
0
),
cmd
.
Bool
(
"user"
))
return
nil
}
func
HyprlandToggleModuleCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
module
:=
cmd
.
Args
()
.
Get
(
0
)
user
:=
cmd
.
Bool
(
"user"
)
status
:=
hyprlandModuleStatus
(
module
,
user
)
switch
status
{
case
"enabled"
:
hyprlandSetModule
(
"disable"
,
module
,
user
)
case
"disabled"
:
hyprlandSetModule
(
"enable"
,
module
,
user
)
}
return
nil
}
func
hyprlandListModules
(
user
bool
,
filter
string
)
{
var
dir
string
if
user
{
dir
=
config
.
Env
.
Hyprland
.
UserModulesDir
}
else
{
dir
=
config
.
Env
.
Hyprland
.
SystemModulesDir
}
entries
,
err
:=
os
.
ReadDir
(
dir
)
if
err
!=
nil
{
fmt
.
Printf
(
"Каталог с модулями не найден: %s"
,
dir
)
return
}
skip
:=
map
[
string
]
bool
{
"hyprland"
:
true
,
"hypridle"
:
true
,
"hyprlock"
:
true
,
"hyprpaper"
:
true
,
"hyprsunset"
:
true
,
"xdph"
:
true
,
}
for
_
,
e
:=
range
entries
{
if
e
.
IsDir
()
||
!
strings
.
HasSuffix
(
e
.
Name
(),
".conf"
)
{
continue
}
module
:=
strings
.
TrimSuffix
(
e
.
Name
(),
".conf"
)
if
skip
[
module
]
{
continue
}
status
:=
hyprlandModuleStatus
(
module
,
user
)
if
filter
==
"enabled"
&&
status
!=
"enabled"
{
continue
}
if
filter
==
"disabled"
&&
status
!=
"disabled"
{
continue
}
switch
status
{
case
"enabled"
:
color
.
Green
(
module
)
case
"disabled"
:
color
.
Yellow
(
module
)
default
:
color
.
Red
(
module
)
}
}
}
func
HyprlandListModulesCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
hyprlandListModules
(
cmd
.
Bool
(
"user"
),
"all"
)
return
nil
}
hyprland/commands.go
View file @
f65678f8
...
...
@@ -17,6 +17,49 @@ func CommandList() *cli.Command {
Usage
:
"Check the Hyprland config"
,
Action
:
CheckHyprland
,
},
{
Name
:
"module"
,
Usage
:
"Hyprland modules"
,
Flags
:
[]
cli
.
Flag
{
&
cli
.
BoolFlag
{
Name
:
"user"
,
Usage
:
"use user modules"
,
Aliases
:
[]
string
{
"u"
},
Value
:
false
,
},
},
Commands
:
[]
*
cli
.
Command
{
{
Name
:
"status"
,
Usage
:
"Hyprland module status"
,
ArgsUsage
:
"module"
,
Action
:
HyprlandModuleStatusCommand
,
},
{
Name
:
"list"
,
Usage
:
"list modules"
,
Action
:
HyprlandListModulesCommand
,
},
{
Name
:
"enable"
,
Usage
:
"enable module"
,
ArgsUsage
:
"module"
,
Action
:
HyprlandModuleEnableCommand
,
},
{
Name
:
"disable"
,
Usage
:
"disable module"
,
ArgsUsage
:
"module"
,
Action
:
HyprlandModuleDisableCommand
,
},
{
Name
:
"toggle"
,
Usage
:
"toggle module"
,
ArgsUsage
:
"module"
,
Action
:
HyprlandToggleModuleCommand
,
},
},
},
},
}
}
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