From e9a7d2029b28b5a21f7e5f56c74b292c33198e0c Mon Sep 17 00:00:00 2001 From: "M.Schirmer" Date: Wed, 7 Jan 2026 17:19:29 +0100 Subject: [PATCH] add quick help within detail-float --- AGENTS.md | 3 + README.md | 1 + lua/test-samurai/core.lua | 54 ++++++++++++++++++ tests/test_samurai_core_spec.lua | 94 ++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 3fb6f5d..a039d59 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,6 +11,9 @@ - **Keine stillen Änderungen**: - Bestehende Features dürfen nicht unbemerkt geändert oder ersetzt werden. - Notwendige Anpassungen zur Koexistenz mehrerer Features müssen klar erkennbar sein. +- **Hilfe-Ansicht aktuell halten**: + - Änderungen und/oder Erweiterungen müssen **immer** die neue Hilfe-Ansicht automatisch aktualisieren. + - Sprache der Hilfe ist wie die README.md immer **englisch**. ## Projektziel - Neovim Plugin: **test-samurai** diff --git a/README.md b/README.md index 51ac2c8..b441a6f 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Additional keymaps: - `qn` -> close the testing floats and jump to the first quickfix entry - `nf` -> jump to the next `[ FAIL ]` entry in the Test-Listing-Float (wraps to the first) - `pf` -> jump to the previous `[ FAIL ]` entry in the Test-Listing-Float (wraps to the last) +- `?` -> show help with TSam commands and standard keymaps in the Detail-Float ## Output UI diff --git a/lua/test-samurai/core.lua b/lua/test-samurai/core.lua index bb27b13..fd3eb1c 100644 --- a/lua/test-samurai/core.lua +++ b/lua/test-samurai/core.lua @@ -43,6 +43,43 @@ local function disable_container_maps(buf) vim.keymap.set("n", "", "", opts) end +local function help_lines() + return { + "Test-Samurai Help", + "", + "TSam Commands:", + " TSamNearest tn", + " TSamFile tf", + " TSamAll ta", + " TSamLast tl", + " TSamFailedOnly te", + " TSamShowOutput to", + "", + "Standard Keymaps:", + " qn Close floats + jump to first quickfix entry", + " nf Next [ FAIL ] in listing", + " pf Previous [ FAIL ] in listing", + "", + "Testing-Float (Listing):", + " Open Detail-Float for selected test", + " Close Testing-Float", + " Focus Detail-Float (press l again for full)", + " Focus Test-Listing-Float", + " z Toggle Detail-Float full width", + " o Jump to test location", + " ? Show this help", + "", + "Testing-Float (Detail):", + " Close Testing-Float", + " Focus Test-Listing-Float", + " h Focus Test-Listing-Float", + " Focus Detail-Float", + " z Toggle Detail-Float full width", + " Close Detail-Float", + " ? Show this help", + } +end + local function get_hardtime() local ok, hardtime = pcall(require, "hardtime") if not ok or type(hardtime) ~= "table" then @@ -626,6 +663,9 @@ local function create_output_win(initial_lines) vim.keymap.set("n", "qn", function() jump_to_first_quickfix() end, { buffer = buf, nowait = true, silent = true }) + vim.keymap.set("n", "?", function() + M.show_help() + end, { buffer = buf, nowait = true, silent = true }) disable_container_maps(buf) state.last_win = listing @@ -690,6 +730,9 @@ local function reopen_output_win() vim.keymap.set("n", "qn", function() jump_to_first_quickfix() end, { buffer = state.last_buf, nowait = true, silent = true }) + vim.keymap.set("n", "?", function() + M.show_help() + end, { buffer = state.last_buf, nowait = true, silent = true }) disable_container_maps(state.last_buf) state.last_win = win @@ -1005,6 +1048,9 @@ local function ensure_detail_buf(lines) vim.keymap.set("n", "qn", function() jump_to_first_quickfix() end, { buffer = buf, nowait = true, silent = true }) + vim.keymap.set("n", "?", function() + M.show_help() + end, { buffer = buf, nowait = true, silent = true }) disable_container_maps(buf) end local clean_lines, highlights = parse_ansi_lines(normalize_output_lines(lines)) @@ -1133,6 +1179,14 @@ function M.open_test_output_at_cursor() open_detail_split(output, border_kind) end +function M.show_help() + if not (state.last_win and vim.api.nvim_win_is_valid(state.last_win)) then + vim.notify("[test-samurai] No test output window", vim.log.levels.WARN) + return + end + open_detail_split(help_lines(), "default") +end + function M.focus_listing() if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then diff --git a/tests/test_samurai_core_spec.lua b/tests/test_samurai_core_spec.lua index e924fe3..44b7d9a 100644 --- a/tests/test_samurai_core_spec.lua +++ b/tests/test_samurai_core_spec.lua @@ -148,4 +148,98 @@ describe("test-samurai core (no bundled runners)", function() assert.equals(1, #last) assert.equals("TestA", last[1].text) end) + + it("shows help with TSam commands and keymaps in the detail float", function() + local runner = { + name = "test-runner-help", + } + + function runner.is_test_file(_bufnr) + return true + end + + function runner.find_nearest(bufnr, _row, _col) + return { file = vim.api.nvim_buf_get_name(bufnr), cwd = vim.loop.cwd(), test_name = "TestA" } + end + + function runner.build_command(spec) + return { cmd = { "echo", "nearest" }, cwd = spec.cwd } + end + + function runner.build_file_command(_bufnr) + return { cmd = { "echo", "file" } } + end + + function runner.build_all_command(_bufnr) + return { cmd = { "echo", "all" } } + end + + function runner.build_failed_command(last_command, _failures, _scope_kind) + return { cmd = { "echo", "failed" }, cwd = last_command and last_command.cwd or nil } + end + + function runner.parse_results(_output) + return { passes = {}, failures = {}, skips = {} } + end + + function runner.output_parser() + return { + on_line = function(_line, _state) + return nil + end, + on_complete = function(output, _state) + return runner.parse_results(output) + end, + } + end + + function runner.parse_test_output(_output) + return {} + end + + function runner.collect_failed_locations(_failures, _command, _scope_kind) + return {} + end + + package.loaded["test-samurai-help-runner"] = runner + test_samurai.setup({ runner_modules = { "test-samurai-help-runner" } }) + + local bufnr = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_name(bufnr, "/tmp/test_samurai_help.go") + vim.bo[bufnr].filetype = "go" + vim.api.nvim_set_current_buf(bufnr) + + local orig_jobstart = vim.fn.jobstart + vim.fn.jobstart = function(_cmd, opts) + if opts.on_exit then + opts.on_exit(nil, 0, nil) + end + return 1 + end + + core.run_nearest() + + local listing_buf = vim.api.nvim_get_current_buf() + local maps = vim.api.nvim_buf_get_keymap(listing_buf, "n") + local has_help = false + for _, map in ipairs(maps) do + if map.lhs == "?" then + has_help = true + break + end + end + assert.is_true(has_help) + + core.show_help() + + local detail_buf = vim.api.nvim_get_current_buf() + local lines = vim.api.nvim_buf_get_lines(detail_buf, 0, -1, false) + local joined = table.concat(lines, "\n") + assert.is_true(joined:find("TSamNearest", 1, true) ~= nil) + assert.is_true(joined:find("TSamShowOutput", 1, true) ~= nil) + assert.is_true(joined:find("tn", 1, true) ~= nil) + assert.is_true(joined:find("to", 1, true) ~= nil) + + vim.fn.jobstart = orig_jobstart + end) end)