diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..bacd807 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,30 @@ +name: Tests + +on: + push: + branches: + - main + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + container: alpine:latest + + steps: + - name: Check out repository code + uses: actions/checkout@v2 + + - name: Install dependencies and Neovim + run: | + apk update + apk add neovim git curl + + - name: Install Plenary + run: | + mkdir -p ~/.config/nvim/pack/plenary/start + git clone --depth 1 /~https://github.com/nvim-lua/plenary.nvim.git ~/.config/nvim/pack/plenary/start/plenary.nvim + + - name: Run tests + run: | + nvim --headless -c "PlenaryBustedFile tests/init.lua" diff --git a/README.md b/README.md index 5cd4332..53fd397 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # 🔖 Recall +![Tests](/~https://github.com/fnune/recall.nvim/actions/workflows/test.yml/badge.svg) + Recall refines the use of [Neovim marks][marks] by focusing on global marks, streamlining their usage and enhancing their visibility and navigability. diff --git a/lua/recall/marking.lua b/lua/recall/marking.lua index d74547a..ac877a0 100644 --- a/lua/recall/marking.lua +++ b/lua/recall/marking.lua @@ -54,6 +54,11 @@ M.remove_mark_if_exists = function() end function M.set_global_mark() + if vim.api.nvim_buf_get_name(0) == "" then + print("Cannot set a global mark in an unsaved buffer") + return + end + local mark = M.next_available_mark() if mark then vim.cmd("mark " .. mark) diff --git a/tests/init.lua b/tests/init.lua new file mode 100644 index 0000000..b52b3ee --- /dev/null +++ b/tests/init.lua @@ -0,0 +1,123 @@ +local luv = require("luv") +local recall = require("recall") + +local function set_lines(buffer, count) + local lines = {} + for i = 1, count do + table.insert(lines, i .. "Lorem ipsum dolor sit amet, consectetur adipiscing elit...") + end + vim.api.nvim_buf_set_lines(buffer, 0, -1, false, lines) +end + +local function place_cursor(line, column) + vim.api.nvim_win_set_cursor(0, { line, column }) +end + +local function count_signs(buffer) + local signs = vim.fn.sign_getplaced(buffer, { name = "RecallMark" })[1].signs + return #signs +end + +describe("Recall", function() + local bufnr + local line_count = 100 + local temp_paths = {} + + before_each(function() + recall.setup({}) + + bufnr = vim.api.nvim_create_buf(true, false) + vim.api.nvim_set_current_buf(bufnr) + set_lines(bufnr, line_count) + + local temp_path = luv.os_tmpdir() .. "/nvim-recall-test-" .. luv.hrtime() .. ".txt" + table.insert(temp_paths, temp_path) + + vim.api.nvim_buf_set_name(bufnr, temp_path) + vim.api.nvim_buf_set_option(bufnr, "modified", false) + vim.cmd("w") + end) + + after_each(function() + for _, temp_path in ipairs(temp_paths) do + os.remove(temp_path) + end + temp_paths = {} + end) + + it("can toggle marks and show/hide signs", function() + recall.toggle() + assert.are.equal(count_signs(bufnr), 1) + + place_cursor(10, 0) + recall.toggle() + assert.are.equal(count_signs(bufnr), 2) + + recall.toggle() + assert.are.equal(count_signs(bufnr), 1) + + place_cursor(1, 0) + recall.toggle() + assert.are.equal(count_signs(bufnr), 0) + end) + + it("can toggle marks regardless of the column", function() + place_cursor(1, 0) + recall.toggle() + assert.are.equal(count_signs(bufnr), 1) + + place_cursor(1, 5) + recall.toggle() + assert.are.equal(count_signs(bufnr), 0) + end) + + it("does not set a mark on an unsaved buffer", function() + assert.are.equal(count_signs(bufnr), 0) + + bufnr = vim.api.nvim_create_buf(true, false) + vim.api.nvim_set_current_buf(bufnr) + + recall.toggle() + assert.are.equal(count_signs(bufnr), 0) + end) + + it("can navigate to next and previous marks", function() + local a_pos = { 1, 1 } + place_cursor(unpack(a_pos)) + recall.toggle() + + local b_pos = { 10, 1 } + place_cursor(unpack(b_pos)) + recall.toggle() + + local c_pos = { 20, 1 } + place_cursor(unpack(c_pos)) + recall.toggle() + + recall.goto_prev() + assert.are.same(b_pos, vim.api.nvim_win_get_cursor(0)) + + recall.goto_prev() + assert.are.same(a_pos, vim.api.nvim_win_get_cursor(0)) + + recall.goto_next() + assert.are.same(b_pos, vim.api.nvim_win_get_cursor(0)) + + recall.goto_next() + assert.are.same(c_pos, vim.api.nvim_win_get_cursor(0)) + + recall.goto_prev() + assert.are.same(b_pos, vim.api.nvim_win_get_cursor(0)) + end) + + it("can clear all marks", function() + recall.toggle() + place_cursor(10, 0) + recall.toggle() + place_cursor(20, 0) + recall.toggle() + + recall.clear() + assert.are.equal(count_signs(bufnr), 0) + end) +end)