From 01cf43dbaa409b5a6cbb1ce2f274c431df1ef23e Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 26 Jun 2024 11:38:54 +0100 Subject: [PATCH] lib/lua: add `isKeyword` and `isIdentifier` Allow testing whether a string is a valid lua identifier or a reserved keyword. --- lib/helpers.nix | 6 ++-- lib/to-lua.nix | 31 +++++++++++++++++ tests/lib-tests.nix | 84 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 3 deletions(-) diff --git a/lib/helpers.nix b/lib/helpers.nix index 5403ba5f..3c610613 100644 --- a/lib/helpers.nix +++ b/lib/helpers.nix @@ -10,10 +10,10 @@ let nixvimUtils = import ./utils.nix { inherit lib nixvimTypes _nixvimTests; }; nixvimOptions = import ./options.nix { inherit lib nixvimTypes nixvimUtils; }; nixvimDeprecation = import ./deprecation.nix { inherit lib; }; - inherit (import ./to-lua.nix { inherit lib; }) toLuaObject; in -{ +rec { maintainers = import ./maintainers.nix; + lua = import ./to-lua.nix { inherit lib; }; keymaps = import ./keymap-helpers.nix { inherit lib nixvimOptions nixvimTypes; }; autocmd = import ./autocmd-helpers.nix { inherit lib nixvimOptions nixvimTypes; }; neovim-plugin = import ./neovim-plugin.nix { @@ -26,7 +26,7 @@ in }; vim-plugin = import ./vim-plugin.nix { inherit lib nixvimOptions nixvimUtils; }; inherit nixvimTypes; - inherit toLuaObject; + inherit (lua) toLuaObject; } // nixvimUtils // nixvimOptions diff --git a/lib/to-lua.nix b/lib/to-lua.nix index 590dcc01..bcdcd56f 100644 --- a/lib/to-lua.nix +++ b/lib/to-lua.nix @@ -1,6 +1,37 @@ { lib }: with lib; rec { + # Whether the string is a reserved keyword in lua + isKeyword = + s: + elem s [ + "and" + "break" + "do" + "else" + "elseif" + "end" + "false" + "for" + "function" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while" + ]; + + # Valid lua identifiers are not reserved keywords, do not start with a digit, + # and contain only letters, digits, and underscores. + isIdentifier = s: !(isKeyword s) && (match "[A-Za-z_][0-9A-Za-z_]*" s) == [ ]; + # Black functional magic that converts a bunch of different Nix types to their # lua equivalents! toLuaObject = diff --git a/tests/lib-tests.nix b/tests/lib-tests.nix index b8bbbf8b..583087f8 100644 --- a/tests/lib-tests.nix +++ b/tests/lib-tests.nix @@ -6,6 +6,45 @@ helpers, }: let + luaNames = { + # Keywords in lua 5.1 + keywords = [ + "and" + "break" + "do" + "else" + "elseif" + "end" + "false" + "for" + "function" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while" + ]; + identifiers = [ + "validIdentifier" + "valid_identifier" + "_also_valid_" + "_weirdNameFMT" + ]; + other = [ + "1_starts_with_digit" + "01234" + "12340" + "kebab-case" + ]; + }; + results = pkgs.lib.runTests { testToLuaObject = { expr = helpers.toLuaObject { @@ -114,6 +153,51 @@ let expected = ''{["c"] = { },["d"] = {["g"] = { }}}''; }; + testIsLuaKeyword = { + expr = builtins.mapAttrs (_: builtins.filter helpers.lua.isKeyword) luaNames; + expected = { + keywords = [ + "and" + "break" + "do" + "else" + "elseif" + "end" + "false" + "for" + "function" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while" + ]; + identifiers = [ ]; + other = [ ]; + }; + }; + + testIsLuaIdentifier = { + expr = builtins.mapAttrs (_: builtins.filter helpers.lua.isIdentifier) luaNames; + expected = { + keywords = [ ]; + identifiers = [ + "validIdentifier" + "valid_identifier" + "_also_valid_" + "_weirdNameFMT" + ]; + other = [ ]; + }; + }; + testUpperFirstChar = { expr = map helpers.upperFirstChar [ "foo"