From 70695d8e22e921f4bb618be26ba60d096e02e860 Mon Sep 17 00:00:00 2001 From: Gage Vander Clay Date: Fri, 8 May 2026 13:39:04 -0500 Subject: [PATCH] fix: improve dock close controls --- CHANGELOG.md | 6 ++++ docs/guides/build-and-deploy.md | 1 + docs/guides/logcat.md | 2 +- docs/reference/keymaps.md | 3 +- lua/android/build/stream.lua | 6 ++++ lua/android/logcat/session/controls.lua | 1 + lua/android/ui/panel.lua | 9 +++++ lua/tests/android/build/stream_test.lua | 34 +++++++++++++++++++ .../logcat/controls/filter_output_test.lua | 19 ++++++++--- lua/tests/android/ui/panel/panel_test.lua | 13 +++++++ lua/tests/helpers/build_stream/panel.lua | 5 +++ 11 files changed, 92 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66ef381..ec581c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on Keep a Changelog and this project adheres to SemVer. ## [Unreleased] +### Changed + +- Build and logcat dock panels now support consistent `q` / `` close + controls, and dock body windows keep a fixed height when additional splits + are opened. + ## [0.6.0] - 2026-03-25 ### Added diff --git a/docs/guides/build-and-deploy.md b/docs/guides/build-and-deploy.md index 9bd0dc4..5a27dc2 100644 --- a/docs/guides/build-and-deploy.md +++ b/docs/guides/build-and-deploy.md @@ -41,6 +41,7 @@ Build output is a two-layer bottom dock: | Key | Action | | --- | --- | +| `q`, `` | Close build output panel | | `f` | Edit build filter text | | `` | On filter row, open filter edit | diff --git a/docs/guides/logcat.md b/docs/guides/logcat.md index a60f7cf..b1b8b30 100644 --- a/docs/guides/logcat.md +++ b/docs/guides/logcat.md @@ -33,7 +33,7 @@ Logcat uses a two-layer bottom dock: | Key | Action | | --- | --- | -| `q` | Close logcat panel | +| `q`, `` | Close logcat panel | | `c` | Clear panel output | | `C` | Clear output and reset pause state | | `p` | Pause or resume output | diff --git a/docs/reference/keymaps.md b/docs/reference/keymaps.md index 442d576..ab69240 100644 --- a/docs/reference/keymaps.md +++ b/docs/reference/keymaps.md @@ -65,7 +65,7 @@ vim.keymap.set("n", "ar", "(AndroidRun)", { remap = true, silent = | Key | Action | | --- | --- | -| `q` | Close panel | +| `q`, `` | Close panel | | `c` | Clear output | | `C` | Clear output and reset pause | | `p` | Pause or resume stream | @@ -80,6 +80,7 @@ vim.keymap.set("n", "ar", "(AndroidRun)", { remap = true, silent = | Key | Action | | --- | --- | +| `q`, `` | Close panel | | `f` | Edit build filter | | `` | On control strip row, open filter edit | diff --git a/lua/android/build/stream.lua b/lua/android/build/stream.lua index f3584df..01fd815 100644 --- a/lua/android/build/stream.lua +++ b/lua/android/build/stream.lua @@ -175,6 +175,12 @@ local function setup_keymaps(session) end end + map("q", function() + panel.close() + end) + map("", function() + panel.close() + end) map("f", function() start_filter_edit(session) end) diff --git a/lua/android/logcat/session/controls.lua b/lua/android/logcat/session/controls.lua index e1b4a35..32cefa4 100644 --- a/lua/android/logcat/session/controls.lua +++ b/lua/android/logcat/session/controls.lua @@ -256,6 +256,7 @@ local function setup_keymaps(session, deps) end end map("q", function() session.on_close() end) + map("", function() session.on_close() end) map("c", function() clear_panel(session) end) map("C", function() reset_output(session) end) map("p", function() toggle_pause(session) end) diff --git a/lua/android/ui/panel.lua b/lua/android/ui/panel.lua index 0173d94..17256d8 100644 --- a/lua/android/ui/panel.lua +++ b/lua/android/ui/panel.lua @@ -144,6 +144,13 @@ local function apply_control_height(height) pcall(vim.api.nvim_win_set_option, control_win_id, "winfixheight", true) end +local function fix_body_height() + if not body_win_id or not vim.api.nvim_win_is_valid(body_win_id) then + return + end + pcall(vim.api.nvim_win_set_option, body_win_id, "winfixheight", true) +end + local function pin_window_buffer(win) if not win or not vim.api.nvim_win_is_valid(win) then return @@ -245,6 +252,7 @@ local function open_dock(options) if body_win_in_current_tab() and control_win_in_current_tab() then vim.api.nvim_win_set_buf(body_win_id, body_buf_id) pin_window_buffer(body_win_id) + fix_body_height() vim.api.nvim_win_set_buf(control_win_id, control_buf_id) pin_window_buffer(control_win_id) apply_control_height(options and options.control_height or header_count) @@ -261,6 +269,7 @@ local function open_dock(options) body_win_id = vim.api.nvim_get_current_win() vim.api.nvim_win_set_buf(body_win_id, body_buf_id) pin_window_buffer(body_win_id) + fix_body_height() vim.cmd("aboveleft split") control_win_id = vim.api.nvim_get_current_win() diff --git a/lua/tests/android/build/stream_test.lua b/lua/tests/android/build/stream_test.lua index 56ca67b..6f60f2a 100644 --- a/lua/tests/android/build/stream_test.lua +++ b/lua/tests/android/build/stream_test.lua @@ -133,6 +133,37 @@ local function start_build_job_registers_filter_keymap() ) end +local function start_build_job_registers_close_keymaps() + local outcome = build_stream_helper.run_filter_build() + + assert.is_true( + outcome.keymaps and outcome.keymaps["n"]["q"], + "q close keymap" + ) + assert.is_true( + outcome.keymaps and outcome.keymaps["n"][""], + "esc close keymap" + ) +end + +local function close_keymap_closes_panel(lhs) + local outcome = build_stream_helper.run_filter_build({ + after_start = function(state) + state.keymaps["n"][lhs]() + end, + }) + + assert.eq(outcome.panel.closed, true, lhs .. " closes panel") +end + +local function q_keymap_closes_panel() + close_keymap_closes_panel("q") +end + +local function esc_keymap_closes_panel() + close_keymap_closes_panel("") +end + local function run_filter_input(options) local opts = options or {} local state = opts.state @@ -303,6 +334,9 @@ function M.run() start_build_job_reports_lines() start_build_job_sets_header() start_build_job_registers_filter_keymap() + start_build_job_registers_close_keymaps() + q_keymap_closes_panel() + esc_keymap_closes_panel() filter_keymap_opens_modal() filter_input_updates_header() filter_input_tracks_body_updates() diff --git a/lua/tests/android/logcat/controls/filter_output_test.lua b/lua/tests/android/logcat/controls/filter_output_test.lua index 4bc689d..63a636d 100644 --- a/lua/tests/android/logcat/controls/filter_output_test.lua +++ b/lua/tests/android/logcat/controls/filter_output_test.lua @@ -153,24 +153,33 @@ local function filter_change_rebuilds_body_from_raw_lines() end) end -local function stopped_session_ignores_late_output() +local function close_keymap_stops_session(lhs) with_filter_output_context(function(ctx, filter_calls, job_callbacks, appended) - ctx.vim_state.keymaps["n"]["q"]() + ctx.vim_state.keymaps["n"][lhs]() job_callbacks.on_stdout({ "late line" }) - assert.eq(filter_calls.count, 0, "stopped session ignores filter") - assert.eq(appended.lines, nil, "stopped session ignores append") + assert.eq(filter_calls.count, 0, lhs .. " stopped session ignores filter") + assert.eq(appended.lines, nil, lhs .. " stopped session ignores append") end) end +local function q_stops_session_ignores_late_output() + close_keymap_stops_session("q") +end + +local function esc_stops_session_ignores_late_output() + close_keymap_stops_session("") +end + function M.run() handle_output_filters_lines_count() handle_output_filters_lines_input() handle_output_filters_lines_filter_arg() handle_output_appends_filtered_lines() filter_change_rebuilds_body_from_raw_lines() - stopped_session_ignores_late_output() + q_stops_session_ignores_late_output() + esc_stops_session_ignores_late_output() end return M diff --git a/lua/tests/android/ui/panel/panel_test.lua b/lua/tests/android/ui/panel/panel_test.lua index 8aa8778..0dbd52b 100644 --- a/lua/tests/android/ui/panel/panel_test.lua +++ b/lua/tests/android/ui/panel/panel_test.lua @@ -78,6 +78,18 @@ local function open_dock_sets_winfixbuf_for_body_and_control_windows() end) end +local function open_dock_sets_winfixheight_for_body_and_control_windows() + panel_vim.with_panel_module( + { on_cmd = panel_vim.on_split_create_window }, + function(panel, api_state) + panel.open({ layout = "dock", control_height = 1 }) + + assert.eq(api_state.win_options[100].winfixheight, true, "body winfixheight") + assert.eq(api_state.win_options[101].winfixheight, true, "control winfixheight") + end + ) +end + local function open_dock_preserve_focus_keeps_origin_window_selected() panel_vim.with_panel_module( { on_cmd = panel_vim.on_split_create_window }, @@ -207,6 +219,7 @@ function M.run() open_creates_split_window_and_configures_buffer() open_sets_winfixbuf_for_inline_window() open_dock_sets_winfixbuf_for_body_and_control_windows() + open_dock_sets_winfixheight_for_body_and_control_windows() open_dock_preserve_focus_keeps_origin_window_selected() open_dock_closes_stale_android_windows_before_creating_new_pair() append_adds_lines_to_open_buffer() diff --git a/lua/tests/helpers/build_stream/panel.lua b/lua/tests/helpers/build_stream/panel.lua index ed1b0c8..1693a04 100644 --- a/lua/tests/helpers/build_stream/panel.lua +++ b/lua/tests/helpers/build_stream/panel.lua @@ -14,6 +14,7 @@ function M.make_panel_state() replaced_body_history = {}, names = nil, name_history = {}, + closed = false, } end @@ -94,6 +95,10 @@ function M.make_panel_stub(panel_state, vim_state) panel_state.names = snapshot panel_state.name_history[#panel_state.name_history + 1] = snapshot end, + close = function() + panel_state.closed = true + return true + end, } end