summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAylur <[email protected]>2024-09-12 00:40:04 +0200
committerGitHub <[email protected]>2024-09-12 00:40:04 +0200
commit6c5d7659a75c093588117c4c28dd046409b3ac8f (patch)
treec120efe485c6d699d29480e12298c2cd7fe4626c
parentd203255ec20bb6e3b2917dd4aee53dee3a090137 (diff)
parent8b75dadc76274692988eb317d3cc6ce1aaa44780 (diff)
Merge pull request #5 from Aylur/nix/lua-builder
lua example, nix builder
-rw-r--r--core/gjs/src/variable.ts4
-rw-r--r--core/lua/astal/binding.lua20
-rw-r--r--core/lua/astal/process.lua4
-rw-r--r--core/lua/astal/variable.lua4
-rw-r--r--core/lua/test.lua8
-rw-r--r--docs/getting-started/installation.md2
-rw-r--r--docs/getting-started/nix.md31
-rw-r--r--docs/getting-started/supported-languages.md3
-rw-r--r--examples/js/simple-bar/README.md2
-rw-r--r--examples/js/simple-bar/widget/Bar.tsx34
-rw-r--r--examples/lua/simple-bar/README.md12
-rw-r--r--examples/lua/simple-bar/app.lua20
-rw-r--r--examples/lua/simple-bar/lib.lua25
-rw-r--r--examples/lua/simple-bar/style.scss88
-rw-r--r--examples/lua/simple-bar/widget/Bar.lua192
-rw-r--r--flake.nix47
-rw-r--r--nix/devshell.nix57
-rw-r--r--nix/lua.nix58
18 files changed, 531 insertions, 80 deletions
diff --git a/core/gjs/src/variable.ts b/core/gjs/src/variable.ts
index 9528ffe..84f8cc5 100644
--- a/core/gjs/src/variable.ts
+++ b/core/gjs/src/variable.ts
@@ -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) {
diff --git a/core/lua/astal/binding.lua b/core/lua/astal/binding.lua
index 50509d1..ba1e6e4 100644
--- a/core/lua/astal/binding.lua
+++ b/core/lua/astal/binding.lua
@@ -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
diff --git a/core/lua/astal/process.lua b/core/lua/astal/process.lua
index 3d10f8b..6f73613 100644
--- a/core/lua/astal/process.lua
+++ b/core/lua/astal/process.lua
@@ -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
diff --git a/core/lua/astal/variable.lua b/core/lua/astal/variable.lua
index 1e894b5..02d6b45 100644
--- a/core/lua/astal/variable.lua
+++ b/core/lua/astal/variable.lua
@@ -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
diff --git a/core/lua/test.lua b/core/lua/test.lua
deleted file mode 100644
index f5123a3..0000000
--- a/core/lua/test.lua
+++ /dev/null
@@ -1,8 +0,0 @@
-local App = require("astal.application")
-
-App:start({
- instance_name = "test",
- main = function()
- App:quit(1)
- end,
-})
diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md
index bbdced9..ef5c6e8 100644
--- a/docs/getting-started/installation.md
+++ b/docs/getting-started/installation.md
@@ -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
diff --git a/docs/getting-started/nix.md b/docs/getting-started/nix.md
index 3c3e8a9..2f320f3 100644
--- a/docs/getting-started/nix.md
+++ b/docs/getting-started/nix.md
@@ -6,19 +6,32 @@ Using Astal on Nix will require you to package your project.
:::code-group
-```nix [typescript.nix]
-# Not documented yet
-```
+```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";
+ };
+ };
-```nix [lua.nix]
-# Not documented yet
+ outputs = { self, nixpkgs, astal }: let
+ system = "x86_64-linux";
+ pkgs = nixpkgs.legacyPackages.${system};
+ in {
+ packages.${system}.default = astal.lib.mkLuaPacakge {
+ inherit pkgs;
+ };
+ };
+}
```
-```nix [python.nix]
+```nix [<i class="devicon-python-plain"></i> Python]
# 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
diff --git a/docs/getting-started/supported-languages.md b/docs/getting-started/supported-languages.md
index f69dd19..7d8fc5f 100644
--- a/docs/getting-started/supported-languages.md
+++ b/docs/getting-started/supported-languages.md
@@ -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)
+![simple-bar](https://github.com/user-attachments/assets/a306c864-56b7-44c4-8820-81f424f32b9b)
## Python
diff --git a/examples/js/simple-bar/README.md b/examples/js/simple-bar/README.md
index 3a4316e..8f733da 100644
--- a/examples/js/simple-bar/README.md
+++ b/examples/js/simple-bar/README.md
@@ -1,6 +1,6 @@
# Simple Bar Example
-![sime-bar](https://github.com/user-attachments/assets/a306c864-56b7-44c4-8820-81f424f32b9b)
+![simple-bar](https://github.com/user-attachments/assets/a306c864-56b7-44c4-8820-81f424f32b9b)
A simple bar for Hyprland using
diff --git a/examples/js/simple-bar/widget/Bar.tsx b/examples/js/simple-bar/widget/Bar.tsx
index d669fd5..492ab1d 100644
--- a/examples/js/simple-bar/widget/Bar.tsx
+++ b/examples/js/simple-bar/widget/Bar.tsx
@@ -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>
}
diff --git a/examples/lua/simple-bar/README.md b/examples/lua/simple-bar/README.md
new file mode 100644
index 0000000..1cebdac
--- /dev/null
+++ b/examples/lua/simple-bar/README.md
@@ -0,0 +1,12 @@
+# Simple Bar Example
+
+![simple-bar](https://github.com/user-attachments/assets/a306c864-56b7-44c4-8820-81f424f32b9b)
+
+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
diff --git a/examples/lua/simple-bar/app.lua b/examples/lua/simple-bar/app.lua
new file mode 100644
index 0000000..8c3359b
--- /dev/null
+++ b/examples/lua/simple-bar/app.lua
@@ -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,
+})
diff --git a/examples/lua/simple-bar/lib.lua b/examples/lua/simple-bar/lib.lua
new file mode 100644
index 0000000..d94db5c
--- /dev/null
+++ b/examples/lua/simple-bar/lib.lua
@@ -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
diff --git a/examples/lua/simple-bar/style.scss b/examples/lua/simple-bar/style.scss
new file mode 100644
index 0000000..f98286e
--- /dev/null
+++ b/examples/lua/simple-bar/style.scss
@@ -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;
+ }
+ }
+}
diff --git a/examples/lua/simple-bar/widget/Bar.lua b/examples/lua/simple-bar/widget/Bar.lua
new file mode 100644
index 0000000..bf70cd5
--- /dev/null
+++ b/examples/lua/simple-bar/widget/Bar.lua
@@ -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
diff --git a/flake.nix b/flake.nix
index 000ded1..f2ae8cf 100644
--- a/flake.nix
+++ b/flake.nix
@@ -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});
- };
- };
};
}
diff --git a/nix/devshell.nix b/nix/devshell.nix
new file mode 100644
index 0000000..936f4b4
--- /dev/null
+++ b/nix/devshell.nix
@@ -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"]
+ );
+ };
+}
diff --git a/nix/lua.nix b/nix/lua.nix
new file mode 100644
index 0000000..a790021
--- /dev/null
+++ b/nix/lua.nix
@@ -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}"
+ ];
+ }