-
Notifications
You must be signed in to change notification settings - Fork 7
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
WIP: feat: code action to add a misspelling to the config file #72
base: main
Are you sure you want to change the base?
WIP: feat: code action to add a misspelling to the config file #72
Conversation
29703cd
to
6111f00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, thank you, and much how I'd approach it too! Some initial suggestions below:
crates/typos-lsp/src/typos.rs
Outdated
/// all config files are read by typos_cli, and the settings are applied in precedence order: | ||
/// | ||
/// <https://github.com/crate-ci/typos/blob/master/docs/reference.md> | ||
pub fn config_files_in_project( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way config resolution works is a bit gnarly.
typos cli will implicitly look for and use the first config file it finds in this order:
- in the current working directory
- in parents of the current working directory
If a config file is provided explicitly by --config
then it will be used together with the implicit file found as per the above, and its settings will take precedence over the implicit file's.
typos lsp tries to mimic this behaviour as closely as possible. It accepts an explicit config file and needs to initialise an equivalent typos cli Instance and decide what it's path
(ie: current working directory) should be. For path
it uses the workspace folder provided when typos lsp is initialised (or the folders change). path
is used to find the first implicit config file as the cli does above. We assume this best mimics how users run typos cli locally or in CI.
NB: it is possible, particularly with nvim, to initialise typos lsp without a workspace folder (see the conditions mentioned here). In these cases the current working directory is effectively set to the root of the filesystem. This means only a config file in the root of the filesystem will be used (together with an explicit config file).
Ok, so what?
Whether or not config resolution is currently optimal (and maybe its not for the case where we don't have a workspace folder) it probably makes sense to only offer config files that would actually be used by the Instance
.
So I think that would mean offering all of:
- the explicit config file, if it has been set.
- a config file based in the current Instance's
path
, whether or not that config file exists.- (optional bonus) config files in ancestors of this path, but only if they already exist.
What do you think, does that makes sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see - this is totally reasonable. I think I misunderstood how the config files are "inherited".
I will change the logic to what you proposed in 1 and 2 👍🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, now the typo can be ignored in two places:
- in the project's configuration file
- in the explicit configuration file
However, it looks like if I remove the project's configuration file, the root is resolved to my home directory. This causes "ignore foo
in the project" to add the ignore to that file instead.
🤔 I'm not sure what causes this. I do have that file in my home directory, so maybe this is some weirdness in the config resolution logic.
Any idea what could be a more reliable way to resolve the project directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you using nvim-lspconfig? It's root_dir logic is:
root_dir = util.root_pattern('typos.toml', '_typos.toml', '.typos.toml'),
ie: it will include ancestors in its search for config files
} | ||
} | ||
|
||
Err(anyhow::anyhow!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI - I've been using anyhow elsewhere in the project and then handling it in the LanguageServer impl like this - which seems to be working so far ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, on a quick glance that looks like anyhow can be used fine in these "worker" functions, and then unwrapped to comply with the return type expected by the language server implementation. I'll see if I can do the same, this looks quite good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did some improvement here, and it works. It also enabled some additional testing since the different concerns are no longer so tightly bound together.
Would you prefer more integration testing? Didn't look into it that much yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one thank you - and yes it would be great to an integration test cover the execute command logic, if that's not too much trouble 🙏
}; | ||
} | ||
|
||
Ok(None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI probably the easiest way to trigger reloading the config file would be to call update_router which resets the router with new Instances (this approach does have a memory leak but that could be solved independently see #11)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks really good, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reloading seems to work for me now!
crates/typos-lsp/src/lsp.rs
Outdated
|
||
std::fs::write( | ||
&config_file_path, | ||
toml::to_string_pretty(&config).expect("cannot serialize config"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this appears to rewrite the entire file, removing comments and inserting empty defaults, eg:
[default]
extend-ignore-identifiers-re = []
extend-ignore-words-re = []
extend-ignore-re = []
could we do a more surgical update, that only modifies default.extend-words
and preserves comments ... perhaps toml_edit would help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice idea, will definitely do this. I didn't realize comments get removed too, that's not good 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toml_edit worked nicely, and now the config file is preserved when ignoring a typo.
5e8403a
to
ef9a6ad
Compare
any update/eta on this? |
ef9a6ad
to
9872ae8
Compare
I kinda forgot about this for a long time... But I think I could still finish it. To do this, I think the following can be worked on:
|
Also rebased to the latest |
My apologies I missed the unanswered questions 🤦 and thank you @mikavilpas for offering to finish this! would be great to get this merged |
I will help you test this PR. I would require help in setting it up with my neovim configuration |
Here's a draft on what could become the solution for #12
This adds a code action like this:
Selecting the code action will make the lsp server to edit the configuration file. Here's what the edits look like in this repository:
Requesting feedback
Some things are a bit open right now, and I'd like to discuss how they should be worked on:
anyhow
, but I couldn't find a way to use it since the tower lsp crate requires a certain error type 😓 Maybe some trait implementations could be added that could automatically handle this?