mirror of
https://github.com/zoriya/astal.git
synced 2026-06-05 19:04:20 +00:00
Merge pull request #5 from Aylur/nix/lua-builder
lua example, nix builder
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import Binding, { type Connectable } from "./binding.js"
|
||||
import { Astal } from "./imports.js"
|
||||
import { interval } from "./time.js"
|
||||
import { interval, idle } from "./time.js"
|
||||
import { execAsync, subprocess } from "./process.js"
|
||||
|
||||
class VariableWrapper<T> extends Function {
|
||||
@@ -101,7 +101,7 @@ class VariableWrapper<T> extends Function {
|
||||
|
||||
drop() {
|
||||
this.variable.emit("dropped")
|
||||
this.variable.run_dispose()
|
||||
idle(() => this.variable.run_dispose())
|
||||
}
|
||||
|
||||
onDropped(callback: () => void) {
|
||||
|
||||
@@ -29,10 +29,13 @@ function Binding:__tostring()
|
||||
end
|
||||
|
||||
function Binding:get()
|
||||
if self.property ~= nil and GObject.Object:is_type_of(self.emitter) then
|
||||
return self.transformFn(self.emitter[self.property])
|
||||
end
|
||||
if type(self.emitter.get) == "function" then
|
||||
return self.transformFn(self.emitter:get())
|
||||
end
|
||||
return self.transformFn(self.emitter[self.property])
|
||||
error("can not get: Not a GObject or a Variable " + self)
|
||||
end
|
||||
|
||||
---@param transform fun(value: any): any
|
||||
@@ -48,17 +51,20 @@ end
|
||||
---@param callback fun(value: any)
|
||||
---@return function
|
||||
function Binding:subscribe(callback)
|
||||
if self.property ~= nil and GObject.Object:is_type_of(self.emitter) then
|
||||
local id = self.emitter.on_notify:connect(function()
|
||||
callback(self:get())
|
||||
end, self.property, false)
|
||||
return function()
|
||||
GObject.signal_handler_disconnect(self.emitter, id)
|
||||
end
|
||||
end
|
||||
if type(self.emitter.subscribe) == "function" then
|
||||
return self.emitter:subscribe(function()
|
||||
callback(self:get())
|
||||
end)
|
||||
end
|
||||
local id = self.emitter.on_notify:connect(function()
|
||||
callback(self:get())
|
||||
end, self.property, false)
|
||||
return function()
|
||||
GObject.signal_handler_disconnect(self.emitter, id)
|
||||
end
|
||||
error("can not subscribe: Not a GObject or a Variable " + self)
|
||||
end
|
||||
|
||||
Binding.__index = Binding
|
||||
|
||||
@@ -72,7 +72,7 @@ function M.exec_async(commandline, on_stdout, on_stderr)
|
||||
local out, err = defualt_proc_args(on_stdout, on_stderr)
|
||||
if type(commandline) == "table" then
|
||||
Astal.Process.exec_asyncv(commandline, function(_, res)
|
||||
local stdout, fail = Astal.exec_asyncv_finish(res)
|
||||
local stdout, fail = Astal.Process.exec_asyncv_finish(res)
|
||||
if fail ~= nil then
|
||||
err(fail)
|
||||
else
|
||||
@@ -81,7 +81,7 @@ function M.exec_async(commandline, on_stdout, on_stderr)
|
||||
end)
|
||||
else
|
||||
Astal.Process.exec_async(commandline, function(_, res)
|
||||
local stdout, fail = Astal.exec_finish(res)
|
||||
local stdout, fail = Astal.Process.exec_finish(res)
|
||||
if fail ~= nil then
|
||||
err(fail)
|
||||
else
|
||||
|
||||
@@ -123,7 +123,9 @@ end
|
||||
|
||||
function Variable:drop()
|
||||
self.variable.emit_dropped()
|
||||
self.variable.run_dispose()
|
||||
Astal.Time.idle(GObject.Closure(function()
|
||||
self.variable.run_dispose()
|
||||
end))
|
||||
end
|
||||
|
||||
---@param callback function
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
local App = require("astal.application")
|
||||
|
||||
App:start({
|
||||
instance_name = "test",
|
||||
main = function()
|
||||
App:quit(1)
|
||||
end,
|
||||
})
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
maintainer: [@Aylur](https://github.com/Aylur)
|
||||
|
||||
Read more about it on the [nix page](./nix)
|
||||
Read more about it on the [nix page](./nix#astal)
|
||||
|
||||
## Arch
|
||||
|
||||
|
||||
+25
-12
@@ -6,19 +6,32 @@ Using Astal on Nix will require you to package your project.
|
||||
|
||||
:::code-group
|
||||
|
||||
```nix [typescript.nix]
|
||||
```nix [<i class="devicon-lua-plain"></i> Lua]
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
astal = {
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, astal }: let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
packages.${system}.default = astal.lib.mkLuaPacakge {
|
||||
inherit pkgs;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
```nix [<i class="devicon-python-plain"></i> Python]
|
||||
# Not documented yet
|
||||
```
|
||||
|
||||
```nix [lua.nix]
|
||||
# Not documented yet
|
||||
```
|
||||
|
||||
```nix [python.nix]
|
||||
# Not documented yet
|
||||
```
|
||||
|
||||
```nix [vala.nix]
|
||||
```nix [<i class="devicon-vala-plain"></i> Vala]
|
||||
# Not documented yet
|
||||
```
|
||||
|
||||
@@ -34,7 +47,7 @@ Example content of a `flake.nix` file that contains your `homeConfigurations`.
|
||||
|
||||
:::code-group
|
||||
|
||||
```nix [flake.nix]
|
||||
```nix [<i class="devicon-nixos-plain"></i> flake.nix]
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
@@ -71,7 +84,7 @@ Example content of `home.nix` file
|
||||
|
||||
:::code-group
|
||||
|
||||
```nix [home.nix]
|
||||
```nix [<i class="devicon-nixos-plain"></i> home.nix]
|
||||
{ inputs, pkgs, ... }:
|
||||
{
|
||||
# add the home manager module
|
||||
|
||||
@@ -25,7 +25,8 @@ components that don't render child nodes dynamically, bars and panels for exampl
|
||||
|
||||
Examples:
|
||||
|
||||
- TODO
|
||||
- [Simple Bar](https://github.com/Aylur/astal/tree/main/examples/lua/simple-bar)
|
||||

|
||||
|
||||
## Python
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Simple Bar Example
|
||||
|
||||

|
||||

|
||||
|
||||
A simple bar for Hyprland using
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ function SysTray() {
|
||||
onClickRelease={self => {
|
||||
menu?.popup_at_widget(self, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null)
|
||||
}}>
|
||||
<icon g_icon={bind(item, "gicon")}/>
|
||||
<icon gIcon={bind(item, "gicon")} />
|
||||
</button>
|
||||
}))}
|
||||
</box>
|
||||
@@ -64,21 +64,27 @@ function BatteryLevel() {
|
||||
}
|
||||
|
||||
function Media() {
|
||||
const player = Mpris.Player.new("spotify")
|
||||
const mpris = Mpris.get_default()
|
||||
|
||||
return <box className="Media">
|
||||
<box
|
||||
className="Cover"
|
||||
valign={Gtk.Align.CENTER}
|
||||
css={bind(player, "coverArt").as(cover =>
|
||||
`background-image: url('${cover}');`
|
||||
)}
|
||||
/>
|
||||
<label
|
||||
label={bind(player, "title").as(() =>
|
||||
`${player.title} - ${player.artist}`
|
||||
)}
|
||||
/>
|
||||
{bind(mpris, "players").as(ps => ps[0] ? (
|
||||
<box>
|
||||
<box
|
||||
className="Cover"
|
||||
valign={Gtk.Align.CENTER}
|
||||
css={bind(ps[0], "coverArt").as(cover =>
|
||||
`background-image: url('${cover}');`
|
||||
)}
|
||||
/>
|
||||
<label
|
||||
label={bind(ps[0], "title").as(() =>
|
||||
`${ps[0].title} - ${ps[0].artist}`
|
||||
)}
|
||||
/>
|
||||
</box>
|
||||
) : (
|
||||
"Nothing Playing"
|
||||
))}
|
||||
</box>
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# Simple Bar Example
|
||||
|
||||

|
||||
|
||||
A simple bar for Hyprland using
|
||||
|
||||
- [Audio library](https://aylur.github.io/astal/libraries/audio).
|
||||
- [Battery library](https://aylur.github.io/astal/libraries/battery).
|
||||
- [Hyprland library](https://aylur.github.io/astal/libraries/hyprland).
|
||||
- [Mpris library](https://aylur.github.io/astal/libraries/mpris).
|
||||
- [Network library](https://aylur.github.io/astal/libraries/network).
|
||||
- [dart-sass](https://sass-lang.com/dart-sass/) as the css precompiler
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/lua
|
||||
local astal = require("astal")
|
||||
local App = astal.App
|
||||
|
||||
local Bar = require("widget.Bar")
|
||||
local src = require("lib").src
|
||||
|
||||
local scss = src("style.scss")
|
||||
local css = "/tmp/style.css"
|
||||
|
||||
astal.exec("sass " .. scss .. " " .. css)
|
||||
|
||||
App:start({
|
||||
css = css,
|
||||
main = function()
|
||||
for _, mon in pairs(App.monitors) do
|
||||
Bar(mon)
|
||||
end
|
||||
end,
|
||||
})
|
||||
@@ -0,0 +1,25 @@
|
||||
local Variable = require("astal").Variable
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.src(path)
|
||||
local str = debug.getinfo(2, "S").source:sub(2)
|
||||
local src = str:match("(.*/)") or str:match("(.*\\)") or "./"
|
||||
return src .. path
|
||||
end
|
||||
|
||||
---@generic T, R
|
||||
---@param arr T[]
|
||||
---@param func fun(T, integer): R
|
||||
---@return R[]
|
||||
function M.map(arr, func)
|
||||
local new_arr = {}
|
||||
for i, v in ipairs(arr) do
|
||||
new_arr[i] = func(v, i)
|
||||
end
|
||||
return new_arr
|
||||
end
|
||||
|
||||
M.date = Variable(""):poll(1000, "date")
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,88 @@
|
||||
$bg: #212223;
|
||||
$fg: #f1f1f1;
|
||||
$accent: #378DF7;
|
||||
$radius: 7px;
|
||||
|
||||
window.Bar {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
background-color: $bg;
|
||||
color: $fg;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
|
||||
button {
|
||||
all: unset;
|
||||
background-color: transparent;
|
||||
|
||||
&:hover label {
|
||||
background-color: transparentize($fg, 0.84);
|
||||
border-color: transparentize($accent, 0.8);
|
||||
}
|
||||
|
||||
&:active label {
|
||||
background-color: transparentize($fg, 0.8)
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
transition: 200ms;
|
||||
padding: 0 8px;
|
||||
margin: 2px;
|
||||
border-radius: $radius;
|
||||
border: 1pt solid transparent;
|
||||
}
|
||||
|
||||
.Workspaces .focused label {
|
||||
color: $accent;
|
||||
border-color: $accent;
|
||||
}
|
||||
|
||||
.FocusedClient {
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
.Media .Cover {
|
||||
min-height: 1.2em;
|
||||
min-width: 1.2em;
|
||||
border-radius: $radius;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.Battery label {
|
||||
padding-left: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.AudioSlider {
|
||||
* {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
icon {
|
||||
margin-right: .6em;
|
||||
}
|
||||
|
||||
margin: 0 1em;
|
||||
|
||||
trough {
|
||||
background-color: transparentize($fg, 0.8);
|
||||
border-radius: $radius;
|
||||
}
|
||||
|
||||
highlight {
|
||||
background-color: $accent;
|
||||
min-height: .8em;
|
||||
border-radius: $radius;
|
||||
}
|
||||
|
||||
slider {
|
||||
background-color: $fg;
|
||||
border-radius: $radius;
|
||||
min-height: 1em;
|
||||
min-width: 1em;
|
||||
margin: -.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
local astal = require("astal")
|
||||
local App = astal.App
|
||||
local Widget = astal.Widget
|
||||
local Variable = astal.Variable
|
||||
local Gdk = astal.Gdk
|
||||
local GLib = astal.GLib
|
||||
local bind = astal.bind
|
||||
local Mpris = astal.require("AstalMpris")
|
||||
local Battery = astal.require("AstalBattery")
|
||||
local Wp = astal.require("AstalWp")
|
||||
local Network = astal.require("AstalNetwork")
|
||||
local Tray = astal.require("AstalTray")
|
||||
local Hyprland = astal.require("AstalHyprland")
|
||||
local map = require("lib").map
|
||||
|
||||
local function SysTray()
|
||||
local tray = Tray.get_default()
|
||||
|
||||
return Widget.Box({
|
||||
bind(tray, "items"):as(function(items)
|
||||
return map(items, function(item)
|
||||
if item.icon_theme_path ~= nil then
|
||||
App:add_icons(item.icon_theme_path)
|
||||
end
|
||||
|
||||
local menu = item:create_menu()
|
||||
|
||||
return Widget.Button({
|
||||
tooltip_markup = bind(item, "tooltip_markup"),
|
||||
on_destroy = function()
|
||||
if menu ~= nil then
|
||||
menu:destroy()
|
||||
end
|
||||
end,
|
||||
on_click_release = function(self)
|
||||
if menu ~= nil then
|
||||
menu:popup_at_widget(self, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, nil)
|
||||
end
|
||||
end,
|
||||
Widget.Icon({
|
||||
g_icon = bind(item, "gicon"),
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end),
|
||||
})
|
||||
end
|
||||
|
||||
local function FocusedClient()
|
||||
local hypr = Hyprland.get_default()
|
||||
local focused = bind(hypr, "focused-client")
|
||||
|
||||
return Widget.Box({
|
||||
class_name = "Focused",
|
||||
visible = focused,
|
||||
focused:as(function(client)
|
||||
return client and Widget.Label({
|
||||
label = bind(client, "title"):as(tostring),
|
||||
})
|
||||
end),
|
||||
})
|
||||
end
|
||||
|
||||
local function Wifi()
|
||||
local wifi = Network.get_default().wifi
|
||||
|
||||
return Widget.Icon({
|
||||
tooltip_text = bind(wifi, "ssid"):as(tostring),
|
||||
class_name = "Wifi",
|
||||
icon = bind(wifi, "icon-name"),
|
||||
})
|
||||
end
|
||||
|
||||
local function AudioSlider()
|
||||
local speaker = Wp.get_default_wp().audio.default_speaker
|
||||
|
||||
return Widget.Box({
|
||||
class_name = "AudioSlider",
|
||||
css = "min-width: 140px;",
|
||||
Widget.Icon({
|
||||
icon = bind(speaker, "volume-icon"),
|
||||
}),
|
||||
Widget.Slider({
|
||||
hexpand = true,
|
||||
on_dragged = function(self)
|
||||
speaker.volume = self.value
|
||||
end,
|
||||
value = bind(speaker, "volume"),
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
local function BatteryLevel()
|
||||
local bat = Battery.get_default()
|
||||
|
||||
return Widget.Box({
|
||||
class_name = "Battery",
|
||||
visible = bind(bat, "is-present"),
|
||||
Widget.Icon({
|
||||
icon = bind(bat, "icon-name"),
|
||||
}),
|
||||
Widget.Label({
|
||||
label = bind(bat, "percentage"):as(function(p)
|
||||
return tostring(math.floor(p * 100)) .. " %"
|
||||
end),
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
local function Media()
|
||||
local player = Mpris.Player.new("spotify")
|
||||
|
||||
return Widget.Box({
|
||||
class_name = "Media",
|
||||
visible = bind(player, "available"),
|
||||
Widget.Box({
|
||||
class_name = "Cover",
|
||||
valign = "CENTER",
|
||||
css = bind(player, "cover-art"):as(function(cover)
|
||||
return "background-image: url('" .. (cover or "") .. "');"
|
||||
end),
|
||||
}),
|
||||
Widget.Label({
|
||||
label = bind(player, "metadata"):as(function()
|
||||
return (player.title or "") .. " - " .. (player.artist or "")
|
||||
end),
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
local function Workspaces()
|
||||
local hypr = Hyprland.get_default()
|
||||
|
||||
return Widget.Box({
|
||||
class_name = "Workspaces",
|
||||
bind(hypr, "workspaces"):as(function(wss)
|
||||
return map(wss, function(ws)
|
||||
return Widget.Button({
|
||||
class_name = bind(hypr, "focused-workspace"):as(function(fw)
|
||||
return fw == ws and "focused" or ""
|
||||
end),
|
||||
on_clicked = function()
|
||||
ws:focus()
|
||||
end,
|
||||
label = bind(ws, "id"):as(tostring),
|
||||
})
|
||||
end)
|
||||
end),
|
||||
})
|
||||
end
|
||||
|
||||
local function Time(format)
|
||||
local time = Variable(""):poll(1000, function()
|
||||
return GLib.DateTime.new_now_local():format(format)
|
||||
end)
|
||||
|
||||
return Widget.Label({
|
||||
class_name = "Time",
|
||||
on_destroy = function()
|
||||
time:drop()
|
||||
end,
|
||||
label = time(),
|
||||
})
|
||||
end
|
||||
|
||||
return function(gdkmonitor)
|
||||
return Widget.Window({
|
||||
class_name = "Bar",
|
||||
gdkmonitor = gdkmonitor,
|
||||
anchor = astal.Astal.WindowAnchor.TOP + astal.Astal.WindowAnchor.LEFT + astal.Astal.WindowAnchor.RIGHT,
|
||||
exclusivity = "EXCLUSIVE",
|
||||
|
||||
Widget.CenterBox({
|
||||
Widget.Box({
|
||||
halign = "START",
|
||||
Workspaces(),
|
||||
FocusedClient(),
|
||||
}),
|
||||
Widget.Box({
|
||||
Media(),
|
||||
}),
|
||||
Widget.Box({
|
||||
halign = "END",
|
||||
Wifi(),
|
||||
AudioSlider(),
|
||||
BatteryLevel(),
|
||||
SysTray(),
|
||||
Time("%H:%M - %A %e."),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
end
|
||||
@@ -8,8 +8,8 @@
|
||||
inherit (builtins) replaceStrings readFile;
|
||||
|
||||
version = replaceStrings ["\n"] [""] (readFile ./version);
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs {inherit system;};
|
||||
system = "x86_64-linux"; # TODO: other architectures
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
|
||||
mkPkg = name: src: inputs:
|
||||
pkgs.stdenv.mkDerivation {
|
||||
@@ -29,6 +29,17 @@
|
||||
outputs = ["out" "dev"];
|
||||
};
|
||||
in {
|
||||
devShells.${system} = import ./nix/devshell.nix {
|
||||
inherit self pkgs;
|
||||
};
|
||||
|
||||
lib = {
|
||||
mkLuaPackage = import ./nix/lua.nix {
|
||||
inherit pkgs;
|
||||
astal = self;
|
||||
};
|
||||
};
|
||||
|
||||
packages.${system} = with pkgs; {
|
||||
docs = import ./docs {inherit self pkgs;};
|
||||
default = self.packages.${system}.astal;
|
||||
@@ -47,37 +58,5 @@
|
||||
tray = mkPkg "astal-tray" ./lib/tray [gtk3 gdk-pixbuf libdbusmenu-gtk3 json-glib];
|
||||
wireplumber = mkPkg "astal-wireplumber" ./lib/wireplumber [wireplumber];
|
||||
};
|
||||
|
||||
devShells.${system} = let
|
||||
buildInputs = with pkgs; [
|
||||
wrapGAppsHook
|
||||
gobject-introspection
|
||||
meson
|
||||
pkg-config
|
||||
ninja
|
||||
vala
|
||||
gtk3
|
||||
gtk-layer-shell
|
||||
json-glib
|
||||
pam
|
||||
gvfs
|
||||
networkmanager
|
||||
gdk-pixbuf
|
||||
wireplumber
|
||||
libdbusmenu-gtk3
|
||||
wayland
|
||||
|
||||
(lua.withPackages (ps: [ps.lgi]))
|
||||
(python3.withPackages (ps: [ps.pygobject3 ps.pygobject-stubs]))
|
||||
gjs
|
||||
];
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
inherit buildInputs;
|
||||
};
|
||||
astal = pkgs.mkShell {
|
||||
buildInputs = buildInputs ++ (builtins.attrValues self.packages.${system});
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
self,
|
||||
pkgs,
|
||||
}: let
|
||||
lua = pkgs.lua.withPackages (ps: [
|
||||
ps.lgi
|
||||
(ps.luaPackages.toLuaModule (pkgs.stdenv.mkDerivation {
|
||||
name = "astal";
|
||||
src = "${self}/core/lua";
|
||||
dontBuild = true;
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/lua/${ps.lua.luaversion}/astal
|
||||
cp -r astal/* $out/share/lua/${ps.lua.luaversion}/astal
|
||||
'';
|
||||
}))
|
||||
]);
|
||||
|
||||
python = pkgs.python3.withPackages (ps: [
|
||||
ps.pygobject3
|
||||
ps.pygobject-stubs
|
||||
]);
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
wrapGAppsHook
|
||||
gobject-introspection
|
||||
meson
|
||||
pkg-config
|
||||
ninja
|
||||
vala
|
||||
gtk3
|
||||
gtk-layer-shell
|
||||
json-glib
|
||||
pam
|
||||
gvfs
|
||||
networkmanager
|
||||
gdk-pixbuf
|
||||
wireplumber
|
||||
libdbusmenu-gtk3
|
||||
wayland
|
||||
|
||||
dart-sass
|
||||
lua
|
||||
python
|
||||
gjs
|
||||
];
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
inherit buildInputs;
|
||||
};
|
||||
astal = pkgs.mkShell {
|
||||
buildInputs =
|
||||
buildInputs
|
||||
++ builtins.attrValues (
|
||||
builtins.removeAttrs self.packages.${pkgs.system} ["docs"]
|
||||
);
|
||||
};
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
defaults: {
|
||||
pkgs ? defaults.pkgs,
|
||||
astal ? defaults.astal,
|
||||
name ? "astal-lua",
|
||||
src,
|
||||
extraLuaPackages ? (ps: []),
|
||||
extraPackages ? [],
|
||||
}: let
|
||||
lua = pkgs.lua.withPackages (ps:
|
||||
(extraLuaPackages ps)
|
||||
++ [
|
||||
ps.lgi
|
||||
(ps.luaPackages.toLuaModule (pkgs.stdenv.mkDerivation {
|
||||
name = "astal";
|
||||
version = "0.1.0";
|
||||
src = "${astal}/core/lua";
|
||||
dontBuild = true;
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/lua/${ps.lua.luaversion}/astal
|
||||
cp -r astal/* $out/share/lua/${ps.lua.luaversion}/astal
|
||||
'';
|
||||
}))
|
||||
]);
|
||||
|
||||
script = ''
|
||||
#!${lua}/bin/lua
|
||||
package.path = package.path .. ";${src}/?.lua"
|
||||
require "app"
|
||||
'';
|
||||
in
|
||||
pkgs.stdenvNoCC.mkDerivation {
|
||||
inherit src name;
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
wrapGAppsHook
|
||||
gobject-introspection
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
extraPackages
|
||||
++ [
|
||||
lua
|
||||
astal.packages.${pkgs.system}.default
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/bin
|
||||
cp -r * $out/bin
|
||||
echo '${script}' > astal-lua
|
||||
install -m 755 astal-lua $out/bin/${name}
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
gappsWrapperArgs = [
|
||||
"--prefix PATH : ${pkgs.lib.makeBinPath extraPackages}"
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user