diff --git a/flake.nix b/flake.nix index abf41a5..5403e1a 100644 --- a/flake.nix +++ b/flake.nix @@ -54,6 +54,14 @@ overlays = [ self.overlays.default ]; }; + nvim-test = pkgs.writeShellScriptBin "nvim-test" '' + export NVIM_PLENARY='${pkgs.vimPlugins.plenary-nvim}' + export NVIM_TREESITTER='${pkgs.vimPlugins.nvim-treesitter}' + + ${pkgs.neovim}/bin/nvim --headless --noplugin -u scripts/minimal_init.lua \ + -c "PlenaryBustedDirectory test/ { minimal_init = './scripts/minimal_init.lua' }" + ''; + tree-sitter-env = pkgs.stdenv.mkDerivation { name = "tree-sitter-env"; @@ -94,6 +102,13 @@ enable = true; }; + nvim-test = { + enable = true; + name = "nvim tests"; + entry = "${nvim-test}/bin/nvim-test"; + pass_filenames = false; + }; + tree-sitter = { enable = true; name = "tree-sitter tests"; @@ -115,6 +130,7 @@ default = pkgs.mkShell { nativeBuildInputs = with pkgs; [ nodejs + nvim-test (tree-sitter.override { webUISupport = true; }) ]; diff --git a/queries/indents.scm b/queries/indents.scm index 911681c..4ac8d24 100644 --- a/queries/indents.scm +++ b/queries/indents.scm @@ -54,6 +54,10 @@ "}" @branch (record_expression "}" @indent_end) +(record_type) @indent +"}" @branch +(record_type "}" @indent_end) + (variable_declaration) @indent ; }}} diff --git a/scripts/minimal_init.lua b/scripts/minimal_init.lua new file mode 100644 index 0000000..3772e97 --- /dev/null +++ b/scripts/minimal_init.lua @@ -0,0 +1,13 @@ +vim.cmd([[set runtimepath+=$NVIM_PLENARY]]) +vim.cmd([[set runtimepath+=$NVIM_TREESITTER]]) + +vim.cmd([[runtime! plugin/plenary.vim]]) +vim.cmd([[runtime! plugin/nvim-treesitter.lua]]) + +vim.o.swapfile = false +vim.bo.swapfile = false + +require("nvim-treesitter.configs").setup({ + indent = { enable = true }, + highlight = { enable = true }, +}) diff --git a/test/corpus/control_flow.txt b/test/corpus/control-flow.txt similarity index 100% rename from test/corpus/control_flow.txt rename to test/corpus/control-flow.txt diff --git a/test/corpus/let_expressions.txt b/test/corpus/let-expressions.txt similarity index 100% rename from test/corpus/let_expressions.txt rename to test/corpus/let-expressions.txt diff --git a/test/indent/classes.tig b/test/indent/classes.tig new file mode 100644 index 0000000..542a40e --- /dev/null +++ b/test/indent/classes.tig @@ -0,0 +1,14 @@ +class A { + var a := 12 + + method method() : int = 1 +} + +type B = class extends A { + var b := 27 + + method another_method() = ( + print("called"); + self.b + self.method() + ) +} diff --git a/test/indent/control-flow.tig b/test/indent/control-flow.tig new file mode 100644 index 0000000..abbadfa --- /dev/null +++ b/test/indent/control-flow.tig @@ -0,0 +1,22 @@ +( + if + 12 + then + 27 + else + 42 + ; + + for + i := 12 + to + 27 + do + 42 + ; + + while + 0 + do + break +) diff --git a/test/indent/functions.tig b/test/indent/functions.tig new file mode 100644 index 0000000..22ce051 --- /dev/null +++ b/test/indent/functions.tig @@ -0,0 +1,14 @@ +primitive long_parameter_list( + a: int, + b: string, + c: type +) + +function f() = + ( + long_parameter_list( + 1, + "2", + nil + ) + ) diff --git a/test/indent/groupings.tig b/test/indent/groupings.tig new file mode 100644 index 0000000..870e0da --- /dev/null +++ b/test/indent/groupings.tig @@ -0,0 +1,10 @@ +let + var a := 42 +in + ( + 12; + 27; + 42 + ); + a +end diff --git a/test/indent/values-and-expressions.tig b/test/indent/values-and-expressions.tig new file mode 100644 index 0000000..5131c30 --- /dev/null +++ b/test/indent/values-and-expressions.tig @@ -0,0 +1,30 @@ +let + type array_of_int = array of int + + type record = { + a: int, + b: string, + c: type + } + + var a := + "a string" +in + array[ + 12 + ] + ; + + array_of_int[ + 27 + ] + of + 42 + ; + + record { + a = 1, + b = "2", + c = nil + } +end diff --git a/test/indent_spec.lua b/test/indent_spec.lua new file mode 100644 index 0000000..b87e677 --- /dev/null +++ b/test/indent_spec.lua @@ -0,0 +1,86 @@ +package.path = package.path .. ";" .. vim.env.NVIM_TREESITTER .. "/?.lua" + +local Runner = require("tests.indent.common").Runner +local XFAIL = require("tests.indent.common").XFAIL + +local runner = Runner:new(it, "./test/indent/", { + tabstop = 2, + shiftwidth = 2, + softtabstop = 0, + expandtab = true, +}) + +describe("indent Tiger:", function() + describe("whole file:", function() + runner:whole_file("../highlight/", { + expected_failures = { + -- NOTE: none for now + }, + }) + runner:whole_file("../tags/", { + expected_failures = { + -- NOTE: none for now + }, + }) + runner:whole_file(".", { + expected_failures = { + -- NOTE: none for now + }, + }) + end) + + describe("new line:", function() + runner:new_line("classes.tig", { on_line = 1, text = "var a := 0", indent = 2 }, "class declaration beginning", XFAIL) + runner:new_line("classes.tig", { on_line = 2, text = "var a := 0", indent = 2 }, "class declaration after field") + runner:new_line("classes.tig", { on_line = 4, text = "var a := 0", indent = 2 }, "class declaration after method") + runner:new_line("classes.tig", { on_line = 5, text = "var a := 0", indent = 0 }, "after class declaration") + runner:new_line("classes.tig", { on_line = 7, text = "var a := 0", indent = 2 }, "class type beginning", XFAIL) + runner:new_line("classes.tig", { on_line = 8, text = "var a := 0", indent = 2 }, "class type after field") + runner:new_line("classes.tig", { on_line = 10, text = "self.a := 0", indent = 4 }, "inside method", XFAIL) + runner:new_line("classes.tig", { on_line = 13, text = "var a := 0", indent = 2 }, "class type after method") + runner:new_line("classes.tig", { on_line = 14, text = "var a := 0", indent = 0 }, "after class type") + + runner:new_line("control-flow.tig", { on_line = 2, text = "true", indent = 4 }, "if condition", XFAIL) + runner:new_line("control-flow.tig", { on_line = 4, text = "true", indent = 4 }, "if consequence", XFAIL) + runner:new_line("control-flow.tig", { on_line = 4, text = "true", indent = 4 }, "if alternative", XFAIL) + runner:new_line("control-flow.tig", { on_line = 10, text = "start := 0", indent = 4 }, "for index start", XFAIL) + runner:new_line("control-flow.tig", { on_line = 12, text = "the_end", indent = 4 }, "for index end", XFAIL) + runner:new_line("control-flow.tig", { on_line = 14, text = "break", indent = 4 }, "for body", XFAIL) + runner:new_line("control-flow.tig", { on_line = 18, text = "true", indent = 4 }, "while condition", XFAIL) + runner:new_line("control-flow.tig", { on_line = 20, text = "break", indent = 4 }, "while body", XFAIL) + + runner:new_line("functions.tig", { on_line = 1, text = "parameter: int,", indent = 2 }, "parameter list beginning", XFAIL) + runner:new_line("functions.tig", { on_line = 2, text = "parameter: int,", indent = 2 }, "parameter list middle") + runner:new_line("functions.tig", { on_line = 4, text = ",parameter: int", indent = 2 }, "parameter list end") + runner:new_line("functions.tig", { on_line = 5, text = "var a := 0", indent = 0 }, "after parameter list") + runner:new_line("functions.tig", { on_line = 7, text = "print(a)", indent = 2 }, "function body", XFAIL) + runner:new_line("functions.tig", { on_line = 9, text = "a,", indent = 6 }, "function call beginning", XFAIL) + runner:new_line("functions.tig", { on_line = 10, text = "a,", indent = 6 }, "function call middle") + runner:new_line("functions.tig", { on_line = 12, text = ",a", indent = 6 }, "function call end") + runner:new_line("functions.tig", { on_line = 13, text = "; print(a)", indent = 4 }, "after function call") + runner:new_line("functions.tig", { on_line = 14, text = "var a := 12", indent = 0 }, "after function declaration", XFAIL) + + runner:new_line("groupings.tig", { on_line = 2, text = "var b := 0", indent = 2 }, "let declarations") + runner:new_line("groupings.tig", { on_line = 3, text = "a := a + 1", indent = 2 }, "after 'in'", XFAIL) + runner:new_line("groupings.tig", { on_line = 4, text = "a := a + 1;", indent = 4 }, "sequence", XFAIL) + runner:new_line("groupings.tig", { on_line = 8, text = "a := a + 1;", indent = 2 }, "after sequence") + runner:new_line("groupings.tig", { on_line = 10, text = "+ 1", indent = 0 }, "after 'end'") + + runner:new_line("values-and-expressions.tig", { on_line = 4, text = "field: record,", indent = 4 }, "record type beginning", XFAIL) + runner:new_line("values-and-expressions.tig", { on_line = 5, text = "field: record,", indent = 4 }, "record type middle") + runner:new_line("values-and-expressions.tig", { on_line = 7, text = ",field: record", indent = 4 }, "record type end") + runner:new_line("values-and-expressions.tig", { on_line = 8, text = "var a := 0", indent = 2 }, "after record type") + runner:new_line("values-and-expressions.tig", { on_line = 10, text = "0", indent = 4 }, "variable declaration init value", XFAIL) + runner:new_line("values-and-expressions.tig", { on_line = 11, text = "+ a", indent = 4 }, "variable declaration init follow-up") + runner:new_line("values-and-expressions.tig", { on_line = 13, text = "a", indent = 4 }, "array index", XFAIL) + runner:new_line("values-and-expressions.tig", { on_line = 14, text = "+ a", indent = 4 }, "array index follow-up") + runner:new_line("values-and-expressions.tig", { on_line = 15, text = "+ a", indent = 2 }, "after array value") + runner:new_line("values-and-expressions.tig", { on_line = 18, text = "a", indent = 4 }, "array expression size", XFAIL) + runner:new_line("values-and-expressions.tig", { on_line = 20, text = "of", indent = 2 }, "array expression after size") + runner:new_line("values-and-expressions.tig", { on_line = 21, text = "a", indent = 4 }, "array expression init value", XFAIL) + runner:new_line("values-and-expressions.tig", { on_line = 25, text = "field = 0,", indent = 4 }, "record expression beginning", XFAIL) + runner:new_line("values-and-expressions.tig", { on_line = 26, text = "field = 0,", indent = 4 }, "record expression middle") + runner:new_line("values-and-expressions.tig", { on_line = 28, text = ",field = 0", indent = 4 }, "record expression end") + runner:new_line("values-and-expressions.tig", { on_line = 29, text = "a := 0", indent = 2 }, "after record expression") + end) +end)