This is a small but functional library that converts your nix configurations into lua format.
Go to file
2024-05-20 17:26:50 +03:00
.gitignore initial commit 2022-11-18 02:36:55 +03:00
COPYING fix license 2022-11-19 04:46:37 +03:00
default.nix add default.nix 2024-04-24 17:01:24 +03:00
flake.lock use makefile instead of script in flake.nix 2022-11-22 10:51:34 +03:00
flake.nix use makefile instead of script in flake.nix 2022-11-22 10:51:34 +03:00
lib.nix fixup do statement 2024-05-20 17:26:50 +03:00
lib.test.nix fixup do statement 2024-05-20 17:26:50 +03:00
Makefile add concat and concatLists 2024-04-17 11:20:56 +03:00 add do statement 2024-05-20 14:22:47 +03:00


This is a small but functional library that converts your nix configurations into Lua format.

This library was initially designed for my personal Neovim flake.


Add nix2lua as input to your flake.nix

  inputs.nix2lua.url = "git+";
  outputs = { nix2lua }:
      luaTable = nix2lua.lib.toLua {
        foo = "bar";

        nvimTree.settings = {
          open_on_setup = true;
          renderer = {
            group_empty = true;
            full_name = true;
    in luaTable;


toLua expr

Returns a string containing Lua representation of expr. Strings, integers, floats, boolean, lists and sets are mapped to their Lua equivalents.

Null will be skipped. This is useful when you want to use an optional value. To render nil you should use the LuaNil function.

toLua { foo = "bar"; }
# { foo = "bar" }
toLua [ 10 "foo" [ "bar" ] ]
#`{ 10, "foo", { "bar" } }


Creates a type that will be mapped by the toLua as nil

toLua LuaNil
# nil

raw expr

Creates a type that instructs toLua not to change the passed expression expr.

toLua (raw "require('bar').baz")
# require('bar').baz

namedField name expr (alias: nf)

Creates a type that represents a named field in the Lua table. This type cannot exist outside a list or set.

This is useful to create table with some named fields.

toLua [
  (namedField "bar" "baz")
# { "foo", bar = "baz" }

join sep expr

Join expressions with a separator

toLua (join "=" ["vim.opt.line" true])
# vim.opt.line = true

concat expr

Joins expressions with an empty string separator

This is alias for join ""

toLua (concat ["hello" "world"])
# helloworld

pipe expr

Joins expressions with a '.' (dot) separator. If list of expressions contains a string it will convert to the raw.

toLua (pipe ["vim" "opt" "line"]);
# vim.opt.line
toLua (pipe ["luasnip" (call0 "setup")]);
# luasnip.setup()

pipe1 lhs rhs

Useful alias for pipe that allow only two arguments.

toLua (pipe1 "luasnip" (call0 "setup"));
# luasnip.setup()

spaceBetween expr

Join expressions with a space separator. You can use it to separate all expressions in the Lua configuration.

This is alias for join " "

toLua (spaceBetween [
  (set "vim.opt.number" true)
  (set "vim.opt.relatednumber" true)
# vim.opt.number = true vim.opt.relatednumber = true

call fnName args

Util to call a Lua function with arguments.

If args is list that each list item render as function argument. Otherwise, it will be rendered as first argument.

toLua (call "setup" [ "foo" "bar" ]);
# setup("foo", "bar")
toLua (call "setup" { foo = "bar" });
# or: toLua (call "setup" [{ foo = "bar" }]);
# setup({ foo = "bar" })

call0 fnName

Call a Lua function without arguments.

This is alias for call fnName [].

toLua (call0 "setup")
# setup()

call1 fnName arg

Call a Lua function with one argument. This is useful when a Lua function has only one argument of type list, and we want to avoid using an inner list.

This is alias for call fnName [arg].

toLua (call1 "setup" [ "foo" "bar" ])
# setup({ "foo", "bar" })

require name

Call a require function to import module with name.

This is alias for call "require" name.

toLua (require "luasnip")
# require("luasnip")

op operation lhs rhs

Make Lua basic operation.

toLua (op "+" 1 2)
# (1 + 2)

There are all aliases for basic Lua operations:

add = op "+";
sub = op "-";
mul = op "*";
div = op "/";
mod = op "%";
exp = op "^";

eq = op "==";
ne = op "~=";
gt = op ">";
lt = op "<";
gte = op ">=";
lte = op "<=";

and = op kw_and;
or' = op kw_or;
not = expr: spaceBetween [ kw_not expr ];

set varName expr

Set an expression to a Lua variable.

toLua (set "vim.opt.number" true);
# vim.opt.number = true

Useful aliases:

lset = l: r: local (set l r);

func fnName params body

Define a function with specific name, parameters and body.

toLua (func "foo" ["bar"] (pipe1 "bar" (call0 "baz"));
# function foo(bar) bar.baz() end

Useful aliases:

func0 = fnName: func fnName [ ];

lfunc = n: p: b: local (func n p b);
lfunc0 = n: b: local (func0 n b);

lambda params body

Define a lambda function with specific parameters and body. Useful to use Lua function inline.

toLua (call "setup" {
  on_attach = lambda ["baz"] (pipe1 "baz" (call0 "bar"))
# setup { on_attach = function (baz) end }

Useful aliases:

lambda0 = lambda [ ];

local expr

A modifier to define a variable or a function in local scope.

toLua (local (set "luasnip" (require "luasnip")));
# local set luasnip = require("luasnip")
toLua (local (func "foo" ["bar"] (pipe1 "bar" (call0 "baz")));
# local function foo(bar) bar.baz() end

return expr

Return expression from a function.

toLua (func "foo" ["bar"] (return (pipe1 "bar" "baz"));
# function foo(bar) return bar.baz end

Useful aliases:

return_void = return null;

ifelse condition trueBody falseBody

Make a Lua if else statement.

toLua (ifelse (eq 10 10) (call "print" "yes") (call "print" "no"));
# if (10 == 10) print("yes") else print("no") end

if' condition trueBody

Make a Lua if statement without else.

toLua (if' (eq 10 10) (call "print" "yes"));
# if (10 == 10) print("yes") end

do body

Limit scope of the variables

toLua (do [(requireTo "foo" "foo")])
# do local set foo = require("foo") end


scope = do


GNU General Public License v3.0 or later

See COPYING to see the full text.