feat: Settings page for the log path and poll interval - #31
Conversation
Add a project-level PersistentStateComponent holding logPath and pollSeconds, and a Configurable for them under Settings | Tools | Stacktale. The poll reads both values when it re-arms rather than capturing them once, so a changed interval takes effect on the next tick instead of only after the project is reopened. An empty path keeps the existing errors-ai.log auto-detect, so the defaults reproduce today's behaviour exactly. The defaults, bounds, and log-path resolution live in a plain-Java StSettings in :core, where the suite covers them: a stored 0 clamping to 1s instead of reaching the poll as a busy loop, a relative path resolving against the project root, and text the filesystem cannot represent being rejected rather than thrown. Closes stacktale#5
GabrielBBaldez
left a comment
There was a problem hiding this comment.
This is a careful piece of work, and thank you for coming back to it — the check-in was meant as an offer, not a nudge, and you more than answered it.
Verified rather than taken on trust:
- 15 tests, 0 failures — 7 parser plus your 8, matching what you reported.
POLL_MILLIS = 3000onmainandDEFAULT_POLL_SECONDS = 3here, so an existing project genuinely notices nothing.- The interval really is read on re-arm rather than captured, so a change lands on the next tick.
StacktaleSettingsregisters through@Service+@Staterather thanplugin.xml, which is why the XML only gained the configurable — correct, and easy to get wrong in the other direction.
Your judgement call is the right one, and I would not invert it. A configured path that has no file should say so rather than fall back to auto-detect: falling back would show reports from a file the user did not choose, and being quietly wrong about which file you are reading is worse than being visibly empty. Same reasoning applies to the && autoDetecting you added to the dumb-mode guard — indexing only matters when detection is doing the work — and I appreciated finding the comment already there explaining it.
Putting the defaults, clamping, and path resolution in :core as plain Java is what made all of the above checkable from a test rather than from an IDE, and it is the part I would point at if someone asked how to add a setting here later.
Thank you also for saying plainly that the poll had moved since the issue was written, instead of quietly working around it. Merging.
|
Merged — thanks @kycasdzxc, that's your first one here. If the project turned out to be useful to you, a ⭐ genuinely helps: stacktale is Either way you're welcome back — the |
Adds a project-level
PersistentStateComponent(logPath,pollSeconds) and aConfigurableunder Settings → Tools → Stacktale — a text field for the path,a spinner for the interval.
One thing that changed since the issue was written: the poll has moved out of
StacktalePanelintoStacktaleReportService, which the tool window and thestatus-bar widget now share. So that is where both settings are read, but the
note on the issue still applies —
poll()reads the interval when it re-armsrather than capturing it once, so a changed interval applies on the next tick
instead of only after the project is reopened.
Defaults reproduce today's behaviour exactly: an empty path keeps the
errors-ai.logauto-detect, and the interval starts at the 3s the plugin hasalways used. An existing project notices nothing until a setting changes.
The defaults, bounds, and path resolution live in a plain-Java
StSettingsin:coreso the suite covers them, per CONTRIBUTING — a stored0clamps to 1srather than reaching the poll as a busy loop, a relative path resolves against
the project root, and text the filesystem cannot represent is rejected instead
of thrown.
StacktaleSettingskeeps the persisted state and applies thoserules; the settings page reads its spinner bounds from the same place.
One judgement call worth flagging: when a path is set but no file is there,
the auto-detect does not run as a fallback. Falling back would quietly show
reports from a file the user did not pick, so the tool window says the
configured path has no file instead. Happy to invert it if you meant the other
way round.
Verification
./gradlew test— 15 green (7 parser + 8 new settings tests)./gradlew build verifyPluginProjectConfiguration verifyPluginStructure—green against IntelliJ IDEA Community 2024.3.5
./gradlew runIde— the sandbox IDE loads the plugin with no errors in the logBasePlatformTestCase(not includedin this PR, since
:plugin's test task is disabled by design): a configuredpath is the file the poll reads, clearing it returns to auto-detect, a missing
configured path yields no reports rather than a silent fallback, and the
settings page round-trips both values.
Closes #5