Skip to content

feat: show window/showMessage[Request] in a panel - #3053

Merged
rchl merged 10 commits into
mainfrom
feat/messages-panel
Oct 10, 2026
Merged

rchl merged 10 commits into
mainfrom
feat/messages-panel

Conversation

@rchl

@rchl rchl commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Fixes #3014

window/showMessage notifications and window/showMessageRequest requests are now shown in a new "LSP Messages" output panel instead of the status bar and a popup in the active view.

  • Each entry shows the time, server name and level, followed by the full message. Line breaks are preserved and the text isn't truncated.
  • window/showMessageRequest actions are rendered as buttons below the message, plus a "Dismiss" button that responds with null. The request stays pending until a button is clicked, so hiding the panel no longer dismisses it accidentally. Once answered, the buttons are replaced by a line with the outcome.
  • When a server exits, its pending requests are marked as expired.
  • The new show_messages_panel_level setting (default 3, info) controls which window/showMessage levels open the panel automatically. Messages below that level are still added to the panel and also shown in the status bar like before. Requests always open the panel.
  • The panel keeps the last 100 entries (pending requests are never dropped).
  • New LSP: Toggle Messages Panel command (Command Palette and main menu) and a context menu in the panel with Clear, Copy and Select All.

Screenshots

A request with actions, waiting for a response:

Messages panel with a pending request

After clicking "Create tsconfig.json":

Messages panel after choosing an action

Assisted-By: Claude Code:claude-opus-5-5

πŸ€– Generated with Claude Code

Messages from servers are now collected in a new "LSP Messages" output
panel instead of being shown in the status bar (window/showMessage) or
in a popup in the active view (window/showMessageRequest).

Requests render their actions as buttons below the message and stay
pending until an action is chosen or the request is dismissed, so they
can no longer be dismissed accidentally. Pending requests are marked as
expired when the server exits.

The new "show_messages_panel_level" setting controls for which message
levels the panel opens automatically. Requests always open the panel.

Fixes #3014

Assisted-By: Claude Code:claude-opus-5-5
@netlify

netlify Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

βœ… Deploy Preview for sublime-lsp ready!

Name Link
πŸ”¨ Latest commit ea915a5
πŸ” Latest deploy log https://app.netlify.com/projects/sublime-lsp/deploys/6aca180b0d227c0008bb7633
😎 Deploy Preview https://deploy-preview-3053--sublime-lsp.netlify.app
πŸ“± Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread LSP.sublime-settings Outdated
Comment on lines +93 to +104
// Messages that servers want to show to the user (`window/showMessage`) are collected in
// the "LSP Messages" panel. Open that panel automatically when a message with a level equal
// to or less than the following is received:
// none: 0 (never open the panel automatically)
// error: 1
// warning: 2
// info: 3
// log: 4
// debug: 5
// Messages that don't open the panel are additionally shown in the status bar.
// Requests that need a response from the user (`window/showMessageRequest`) always open the panel.
"show_messages_panel_level": 3,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that many servers seem to trigger window/showMessage. For example pyright does:

19:57:50 LSP-basedpyright ERROR
    venv .venv subdirectory not found in venv path /usr/local/workspace/sublime-packages/LSP-aurelia.

so it probably would get too annoying to have this enabled by default.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that specific error is kinda fair because that package specifies:

[tool.basedpyright]
venvPath = "."
venv = ".venv"

but the venv isn't created.

I guess people should test this and see if it's too trigger happy.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think default should be 0 because the status bar message is also the current behavior for non-request messages.

@rchl rchl Oct 6, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure but there are many issues with the existing solution like no line breaks support and impossible to not miss, so this could be considered as an improvement.

Having feature enabled by default exposes it to the people who otherwise would not even notice that it exists. And then they still have an option of disabling it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that 3 is too high. Error messages are usually important though. Maybe set to 1 so it only pops up for error messages?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know any servers that trigger info messages? I would like to see what the experience is then. But I can imagine that it could get annoying.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, basedpyright does at startup. See: #3053 (comment)

@rchl rchl Oct 10, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is value 1 OK or do you both still prefer to set it to disabled by default?

I guess in this case I'm leaning towards making user notice it and potentially disable if it gets annoying rather than missing the feature completely since I think the status approach is not really a good one.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I still kinda think that 3 would be better than 1 since this is about window/showMessage and not window/logMessage. The server really wants to communicate something to the user in that case.

@rwols rwols self-assigned this Oct 5, 2026
Comment thread plugin/core/messages_panel.py Resolved
Comment thread LSP.sublime-settings Outdated
Comment on lines +93 to +104
// Messages that servers want to show to the user (`window/showMessage`) are collected in
// the "LSP Messages" panel. Open that panel automatically when a message with a level equal
// to or less than the following is received:
// none: 0 (never open the panel automatically)
// error: 1
// warning: 2
// info: 3
// log: 4
// debug: 5
// Messages that don't open the panel are additionally shown in the status bar.
// Requests that need a response from the user (`window/showMessageRequest`) always open the panel.
"show_messages_panel_level": 3,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think default should be 0 because the status bar message is also the current behavior for non-request messages.

Comment thread plugin/core/messages_panel.py Resolved
@rchl rchl changed the title feat: show window/showMessage and window/showMessageRequest in a panel feat: show window/showMessage[Request] in a panel Oct 6, 2026
@rchl rchl changed the title feat: show window/showMessage[Request] in a panel feat: show window/showMessage[Request] in a panel Oct 6, 2026
Comment thread plugin/core/messages_panel.py Outdated
return "\n".join(lines)

def render_buttons(self) -> str:
buttons = [(str(idx), action['title'], idx == 0) for idx, action in enumerate(self.actions)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about this a bit. I think I introduced the primary class for the button in the rename panel because in that case it's used for the hardcoded "Apply" button.

But I'm not sure if it makes sense here to highlight the first button (with primary class), because there isn't any definition for that or any predefined ordering for the actions given in the LSP specs. So maybe it's wrong to just take the first button as "primary" (which I would interpret as something like the "preferred" or "confirm" option), and instead it would be better to use false for all available actions?

Like here it's kind of weird that the first button has a special color, when all 3 available actions are kind of independent without any prefernce for the item to select (this is a message request after running a unit test):

Image

And it might even be slightly misleading that people might think it would highlight a focused button for keyboard input (Enter or arrow keys), which is not the case.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the same time I've made the dismiss button less prominent since it's the one that LSP adds itself

rchl added 4 commits October 10, 2026 12:45
The LSP specification doesn't define a preferred action for
window/showMessageRequest, so highlighting the first one as primary
suggested a recommendation (or keyboard focus) that doesn't exist. All
server actions now share the same style, and the Dismiss button added by
LSP uses a new, less prominent secondary style.

Assisted-By: Claude Code:claude-opus-5-5

@rwols rwols left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd change the default for window/logMessage to 1 or 0, but other than that LGTM.

@rwols

rwols commented Oct 10, 2026

Copy link
Copy Markdown
Member

I thought LSP-basedpyright prints a lot of window/logMessage at startup, and it does:

:: [15:49:50.135] <-  LSP-basedpyright window/logMessage: {'type': 3, 'message': 'Loading pyproject.toml file at /home/raoul/.config/sublime-text-3/Packages/LSP/pyproject.toml'}
:: [15:49:50.135] <-  LSP-basedpyright window/logMessage: {'type': 3, 'message': 'Setting pythonPath for service "LSP": "/home/raoul/.config/sublime-text-3/Packages/LSP/.venv/bin/python"'}
:: [15:49:50.135] <-  LSP-basedpyright window/logMessage: {'type': 3, 'message': 'No include entries specified; assuming /home/raoul/.config/sublime-text-3/Packages/LSP'}
:: [15:49:50.136] <-  LSP-basedpyright window/logMessage: {'type': 3, 'message': 'Auto-excluding **/node_modules'}
:: [15:49:50.136] <-  LSP-basedpyright window/logMessage: {'type': 3, 'message': 'Auto-excluding **/__pycache__'}
:: [15:49:50.136] <-  LSP-basedpyright window/logMessage: {'type': 3, 'message': 'Auto-excluding **/.*'}

but I don't see these appear in the new "Messages" panel... Now I'm a bit confused. I thought window/logMessage messages should also appear there?

@jwortmann

Copy link
Copy Markdown
Member

window/logMessage is printed to the console (and error severity additionally as a status bar message), but only if log_debug setting is enabled.
window/showMessage appears in this panel.

I assume the intention behind window/showMessage in the LSP specs was to show it as a notification (like a toast or permanent floating popup) in the UI. VSCode has a much better UI for that:

notifications

I think those kind of notifications are less annoying because they take less space than the full panel at the bottom, and then it would be useful to always show them for all possible severities. But ST doesn't have that UI, and that's why I'd prefer opt-in for auto-open the panel on new messages.

Perhaps we should create a feature request for a better notification system in ST.

@rchl

rchl commented Oct 10, 2026

Copy link
Copy Markdown
Member Author

Perhaps we should create a feature request for a better notification system in ST.

I guess we should. It was mentioned many times in various places but perhaps nobody got around to creating an issue for it.

@rwols

rwols commented Oct 10, 2026

Copy link
Copy Markdown
Member

window/logMessage is printed to the console (and error severity additionally as a status bar message), but only if log_debug setting is enabled.
window/showMessage appears in this panel.

Right... then... I think the default can actually stay at 3. I was thinking of window/logMessage.

@jwortmann

Copy link
Copy Markdown
Member

I'm okay to go with 1 by default for now and I guess I can disable it in my user settings if it gets too annoying.

@rwols

rwols commented Oct 10, 2026

Copy link
Copy Markdown
Member

Perhaps we should create a feature request for a better notification system in ST.

That will never happen :)

@rchl
rchl merged commit 54023eb into main Oct 10, 2026
9 checks passed
@rchl
rchl deleted the feat/messages-panel branch October 10, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle window/showMessage better

3 participants