From b2217777193a974ba8adb575280d3f18b1ea07db Mon Sep 17 00:00:00 2001 From: Alistair-Afton Date: Wed, 16 Sep 2026 16:38:03 +0200 Subject: [PATCH 1/2] source: validate cursor before source lookup Move the delete lookup after cursor validation so an inactive keyboard cursor produces the intended operator error instead of a nil-position traceback. Add regression coverage for both add and delete. --- changelog.txt | 1 + source.lua | 2 +- test/source.lua | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/source.lua diff --git a/changelog.txt b/changelog.txt index 1ed30ae501..21687fe036 100644 --- a/changelog.txt +++ b/changelog.txt @@ -34,6 +34,7 @@ Template for new versions: ## Fixes - `bodyswap`: fix "invalid argument count" when the target unit has no nemesis record +- `source`: report a useful error when no keyboard cursor is active - `fix/loyaltycascade`: guard against citizens that are not historical figures and emit a warning. - `gui/siegemanager`: fix nil index if there are no siege engines on the map diff --git a/source.lua b/source.lua index 67d052f95b..711c7324cd 100644 --- a/source.lua +++ b/source.lua @@ -132,12 +132,12 @@ function main(args) end local targetPos = guidm.getCursorPos() - local index = find_liquid_source_at_pos(targetPos) if command == 'delete' then if not targetPos then qerror("Please place the cursor where there is a source to delete") end + local index = find_liquid_source_at_pos(targetPos) if index then delete_liquid_source(targetPos) print(('Deleted source at %s'):format(formatPos(targetPos))) diff --git a/test/source.lua b/test/source.lua new file mode 100644 index 0000000000..10554899c4 --- /dev/null +++ b/test/source.lua @@ -0,0 +1,23 @@ +config = { + mode = 'fortress', + target = 'source', +} + +local guidm = require('gui.dwarfmode') +local source = reqscript('source') + +function test.delete_requires_cursor() + mock.patch(guidm, 'getCursorPos', function() end, function() + expect.error_match( + 'Please place the cursor where there is a source to delete', + function() source.main{'delete'} end) + end) +end + +function test.add_requires_cursor() + mock.patch(guidm, 'getCursorPos', function() end, function() + expect.error_match( + 'Please place the cursor where you would like a source', + function() source.main{'add', 'water'} end) + end) +end From c78988cbb4bac60e82b229acdc9f1fc96b287460 Mon Sep 17 00:00:00 2001 From: Alistair-Afton Date: Tue, 22 Sep 2026 03:33:53 +0200 Subject: [PATCH 2/2] source: restore changelog entry lost in merge --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index ed8173e735..0ebd730bbd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -38,6 +38,7 @@ Template for new versions: - `caravan`: fix doubled "total value of items marked for trade" after toggling filter options, and keep item marks when switching between filter views in the ``Bring goods to depot`` overlay - `fix/loyaltycascade`: guard against citizens that are not historical figures and emit a warning. - `gui/siegemanager`: fix nil index if there are no siege engines on the map +- `source`: report a useful error when no keyboard cursor is active ## Misc Improvements - `caravan`: the ``Bring goods to depot``, ``Trade``, and ``Assign items for display`` overlays now allow searching for items with non-ASCII characters in their description