Repository navigation
Conversation
When a linter package is removed, Sublime unloads its plugin module and pops it from sys.modules, but the linter class stays in persist.linter_classes and keeps linting every matching view until Sublime is restarted. Before electing linters for a view, drop the ones whose module is no longer in sys.modules. assign_linters_to_buffer already clears the errors of linters that are no longer assigned to a view. Fixes #1998 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Replace the check in elect() with an event, as suggested in the PR discussion. Observe 'ignored_packages' and Package Control's settings and, shortly after they change, unregister the linters whose plugin is disabled or whose module Sublime has unloaded (removed package), then call sublime_linter_config_changed so open views drop the linter and its errors right away. Fixes #1998 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
| klass.__module__ not in sys.modules | ||
| or klass.plugin_name in disabled_packages |
There was a problem hiding this comment.
Disabling a package should unload it, so the first check is likely enough to detect both cases. However, we depend on the fact that Sublime actually has unloaded them already. And that introduces some number guessing: Does that take 1s or rather 5s.
| .get('in_process_packages', []) | ||
| ) | ||
|
|
||
| if names := persist.forget_unloaded_linters(ignored - in_process): |
There was a problem hiding this comment.
We run here always, when anything has changed in the main Preferences. That is unnecessary often. We need a lens into the actual key/values we're interested in.
Now I think: If we capture the active state on load, and we compute just the delta of active packages or removed packages, then we actually know which packages we need to de-register.
We can't grab packages that are added and removed the hacker way, by cloning and deleting directories, that way.
These we could grab when we just pre-select in elect, only the linters that are actually available. This was in fact the first attempt. The only downside was that we didn't know how to call sublime_linter_config_changed to make changes visible for all. ...
That needs some thinking still.
Address review: instead of reacting to every change of the preferences and guessing when Sublime has unloaded a plugin, remember the disabled packages when SublimeLinter loads and compute the delta on each change. The linters of the newly disabled packages are unregistered, everything else is left alone. Package Control disables a package before it removes or upgrades it, so this covers those as well. Packages that are removed by deleting their directory are not covered. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtRdpWmSGFACg8HR3Vpk3d
|
Thanks, that is a better design. I reworked it along your suggestion (pushed as a new commit):
Not covered, as you said: packages that are deleted by hand. I have not tried the "only elect linters that are actually available" idea from the first attempt, since you said that still needs thinking (how to make Checked live: with SublimeLinter-pycodestyle installed, adding it to |
|
The last commit is worse than the one before. Donald, that is not mechanical work and you have to think actually and steer the agent. |
|
Sometimes Claude appears smart but 'under the surface' acts like farm yard
chicken. The bird.
…On Wed, Sep 30, 2026, 1:06 AM herr kaste ***@***.***> wrote:
*kaste* left a comment (SublimeLinter/SublimeLinter#1999)
<#1999 (comment)>
The last commit is worse than the one before. Donald, that is not
mechanical work and you have to think actually and steer the agent.
—
Reply to this email directly, view it on GitHub
<#1999?email_source=notifications&email_token=BYZWW7ZVY4MY4BY6TSIN4Z35RSWJDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKOJQGYYDENJWGA22M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-5906025605>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BYZWW7ZF3KSVKYZKMV27WF35RSWJDAVCNFSNUABEKJSXA33TNF2G64TZHMYTGNZYGIYDEOJ3JFZXG5LFHM2TMMZUHA3TCNRTGGQXMAQ>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
I do not want to think about what you go through.
My subscriptions have run out. I have started a patreon. I do not know
how to promote it, though. It appears to be at
https://patreon.com/c/dpchitester.
Can't do more of the PRs at until perhaps a week or so. Sorry to let you
down.
On Wed, Sep 30, 2026, 3:52 AM Donald Chitester ***@***.***>
wrote:
… Sometimes Claude appears smart but 'under the surface' acts like farm yard
chicken. The bird.
On Wed, Sep 30, 2026, 1:06 AM herr kaste ***@***.***> wrote:
> *kaste* left a comment (SublimeLinter/SublimeLinter#1999)
> <#1999 (comment)>
>
> The last commit is worse than the one before. Donald, that is not
> mechanical work and you have to think actually and steer the agent.
>
> —
> Reply to this email directly, view it on GitHub
> <#1999?email_source=notifications&email_token=BYZWW7ZVY4MY4BY6TSIN4Z35RSWJDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKOJQGYYDENJWGA22M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-5906025605>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/BYZWW7ZF3KSVKYZKMV27WF35RSWJDAVCNFSNUABEKJSXA33TNF2G64TZHMYTGNZYGIYDEOJ3JFZXG5LFHM2TMMZUHA3TCNRTGGQXMAQ>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>
|
|
Have Max plan now. But can't help with that. If Claude not good enough,
then I am certainly not better.
On Wed, Sep 30, 2026, 6:01 AM Donald Chitester ***@***.***>
wrote:
… I do not want to think about what you go through.
My subscriptions have run out. I have started a patreon. I do not know
how to promote it, though. It appears to be at
https://patreon.com/c/dpchitester.
Can't do more of the PRs at until perhaps a week or so. Sorry to let you
down.
On Wed, Sep 30, 2026, 3:52 AM Donald Chitester ***@***.***>
wrote:
> Sometimes Claude appears smart but 'under the surface' acts like farm
> yard chicken. The bird.
>
> On Wed, Sep 30, 2026, 1:06 AM herr kaste ***@***.***>
> wrote:
>
>> *kaste* left a comment (SublimeLinter/SublimeLinter#1999)
>> <#1999 (comment)>
>>
>> The last commit is worse than the one before. Donald, that is not
>> mechanical work and you have to think actually and steer the agent.
>>
>> —
>> Reply to this email directly, view it on GitHub
>> <#1999?email_source=notifications&email_token=BYZWW7ZVY4MY4BY6TSIN4Z35RSWJDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKOJQGYYDENJWGA22M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-5906025605>,
>> or unsubscribe
>> <https://github.com/notifications/unsubscribe-auth/BYZWW7ZF3KSVKYZKMV27WF35RSWJDAVCNFSNUABEKJSXA33TNF2G64TZHMYTGNZYGIYDEOJ3JFZXG5LFHM2TMMZUHA3TCNRTGGQXMAQ>
>> .
>> You are receiving this because you authored the thread.Message ID:
>> ***@***.***>
>>
>
|
|
(Written by Claude, the AI assistant doing this work for dpc00; the earlier replies in this thread from this account were written by dpc00 himself.) Thank you for the careful review, and sorry that the last commit made it worse. I do not want to push a third guess, so here is where this stands and one question.
Which would you rather have: the first commit's approach (and accept that other views refresh on their next lint), or something else you have in mind? If you prefer the first one I can reset the branch to it and keep its test. If this needs more design thinking than I can offer, feel free to close it, or to take any part of it: #1998 stays the place for the design. |
Fixes #1998.
Reworked twice following the discussion here (thanks @kaste). Latest version, after the review of the observer:
What happens today: when a linter package is disabled or removed, Sublime unloads its plugin, but nothing tells SublimeLinter, so the class stays in
persist.linter_classesand keeps linting until Sublime is restarted.What this does:
plugin_loadedremembers the currentignored_packages(module levelignored_packages) and observesPreferences.sublime-settings;plugin_unloadedclears the observer.on_preferences_changedcomputes the delta: the packages that are inignored_packagesnow but were not before. Changes that do not add a package (any other preference, enabling a package, a package that was already ignored) do nothing. No timer and no waiting for Sublime to unload anything.persist.forget_linters_of_packages(packages)unregisters the linters whoseklass.plugin_nameis one of those packages and returns their names.sublime.run_command('sublime_linter_config_changed')runs once, so open views re-lint, lose the linter via the existingassign_linters_to_buffer, and their errors are cleared.Package Control disables a package (
disable_packages({REMOVE: ...}), inpackage_tasks.remove_packages) before it removes it, and does the same before upgrades, so removing and upgrading are covered by the same event. A package that comes back (re-enabled, upgraded) registers its linter again when Sublime loads the plugin.Not covered: a package that is deleted from disk by hand, without Package Control and without touching
ignored_packages, gives no event; that still needs a restart. As discussed, that would need another mechanism (e.g. only electing linters that are actually available).Verified live (Sublime Text 4215, this branch loaded as
SublimeLinter): installed SublimeLinter-pycodestyle (persist.linter_classes == ['pycodestyle']), added the package toignored_packages: the linter was gone frompersist.linter_classesa moment later without restarting; removing it fromignored_packagesagain broughtpycodestyleback. I did not run Package Control's interactive remove command end to end for this version (the earlier version was verified withremove_package).Tests:
tests/test_forget_unloaded_linters.py(7 tests, no windows needed):forget_linters_of_packagesforgets only the given packages' linters and nothing for unknown packages;on_preferences_changedforgets the linter and re-lints once when a package is newly disabled, and does nothing for an unrelated change, for a newly disabled package without a linter, for a package that was already disabled, or when a package is enabled. They pass in Sublime Text 4215 (run in the plugin host); flake8 with the project's config is clean. I did not re-run the full suite.🤖 Generated with Claude Code
https://claude.ai/code/session_01WtRdpWmSGFACg8HR3Vpk3d