Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propagate air.toml settings to client #160

Merged
merged 22 commits into from
Jan 17, 2025
Merged

Conversation

lionel-
Copy link
Collaborator

@lionel- lionel- commented Jan 15, 2025

Closes #160.

Controlled by air.settingsBackpropagation. Uses the same approach as the editorconfig extension: when the active editor changes we apply the air.toml settings to the active editor.

We send custom tomlSettings LSP notifications to the client:

  • For all open documents when an air.toml file is changed.
  • For a single document when a document is opened.

The client maintains a map of settings. Ideally we wouldn't have to do that but in practice we need to because invisible editors can't have their settings changed. So instead of changing the settings when the notification arrives, we change it when the active editor changes.

Unlike editorconfig, we change indentSize rather than tabSize. This is for consistency with the principle that tabSize is a user preference setting. Note that it seems some VS Code feature such as move line up are not affected by indentSize and instead use tabSize. There might be other bugs of this kind, which could explain why editorconfig decided to change tabSize.

Copy link
Collaborator

@DavisVaughan DavisVaughan left a comment

Choose a reason for hiding this comment

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

It seems to work pretty well in practice. I mostly have a number of naming questions and an aversion to sending all of Settings over to the client right now

crates/lsp/src/main_loop.rs Show resolved Hide resolved
crates/lsp/src/notifications.rs Show resolved Hide resolved
use crate::{main_loop::LspState, workspaces::WorkspaceSettings};

#[derive(serde::Serialize, serde::Deserialize)]
struct SettingsNotifications {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
struct SettingsNotifications {
struct DidChangeFileSettings {

I would love if we could use names that feel like "real" LSP notifications

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good idea

Copy link
Collaborator Author

@lionel- lionel- Jan 16, 2025

Choose a reason for hiding this comment

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

Hmm... But we send this notification in did_open as well, not necessarily when a toml changed.

How about air/syncFileSettings? It seems like we do need a new prefix here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

We agreed air/syncFileSettings is great 👍

crates/lsp/src/notifications.rs Outdated Show resolved Hide resolved
crates/lsp/src/notifications.rs Outdated Show resolved Hide resolved
editors/code/src/lsp-ext.ts Outdated Show resolved Hide resolved
editors/code/src/lsp-ext.ts Outdated Show resolved Hide resolved
editors/code/src/settings.ts Show resolved Hide resolved
editors/code/src/settings.ts Outdated Show resolved Hide resolved
if (file.startsWith("file:///")) {
file = url.fileURLToPath(file);
}
return path.normalize(file);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Something doesn't seem quite right with indent-width. If I add a air.toml to dplyr and add indent-width = 4 and switch back to src.R then I see this

Screenshot 2025-01-15 at 12 39 40 PM Screenshot 2025-01-15 at 12 40 17 PM

Copy link
Collaborator

Choose a reason for hiding this comment

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

If you grep for export class ChangeIndentationSizeAction extends EditorAction { in the positron source, you'll see that it seems like it updates both indentSize and tabSize to keep things in sync!

Screenshot 2025-01-15 at 12 43 59 PM

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe if indent_style === "space" we also set tabSize? That keeps them in sync, but still allows for user customizable tab size when indent_style = "tab"


Interestingly if you have a tabSize = 4 but indentSize = 2 and actually format with tabs, VS Code does show you a little vertical line at the 2 space marker, even though the tab has a visual size of 4 (i.e. it visually shows you the info for indentSize)

Screenshot 2025-01-15 at 1 02 55 PM

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wondered what's the right thing to do here. If we keep them in sync, we're working against an explicit VS Code feature, namely that you can set tabSize to be different than indentSize when insertSpaces is true, so that you can use tabs to format tables. You could imagine tabSize be set in a settings.json file. And the tables would be protected by air: ignore comments.

We can just not support this. According to threads in the vscode repo it's mostly needed for old corporate codebases. I'd be surprised to see R users miss this feature.

And then we avoid the strange mismatch in the status bar that I agree is confusing.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm happy to not support this edge case

Copy link
Collaborator

@DavisVaughan DavisVaughan left a comment

Choose a reason for hiding this comment

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

Check out #173 first and see if you agree. I've been keeping the serde derives minimal so far with these types.

editors/code/src/lsp.ts Outdated Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

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

Really loving everything in one file!

crates/lsp/src/handlers_state.rs Outdated Show resolved Hide resolved
@lionel-
Copy link
Collaborator Author

lionel- commented Jan 17, 2025

Check out #173 first and see if you agree. I've been keeping the serde derives minimal so far with these types.

I don't disagree but I can't promise they won't creep back in over the course of a PR that changes direction in terms of serde requirements... I don't think such derivations on non-generated types bloat the binary that much? I agree that it's nice to avoid implying a type crosses an interop boundary though.

@lionel- lionel- force-pushed the feature/air-toml-propagation branch from de0d6d2 to 884f555 Compare January 17, 2025 08:06
@lionel- lionel- merged commit 2d93f42 into main Jan 17, 2025
5 checks passed
@lionel- lionel- deleted the feature/air-toml-propagation branch January 17, 2025 08:08
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.

2 participants