fix(lsp): renaming of flag variables (#14890)

<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

This PR fixes a bug: renaming on a flag variable removes the leading
`--` in the signature.

<img width="257" alt="image"
src="https://github.com/user-attachments/assets/767c62de-f3a0-4a07-9786-61b21e8cfcb6"
/>

Gets the following before this PR:

```nushell
export def foooo [
  p: int
] {
  $p
}
```

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the
tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
This commit is contained in:
zc he 2025-01-22 20:25:30 +08:00 committed by GitHub
parent cdb082e92d
commit 84c720daf5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 40 additions and 30 deletions

5
Cargo.lock generated
View File

@ -3202,13 +3202,14 @@ dependencies = [
[[package]]
name = "lsp-server"
version = "0.7.7"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9"
checksum = "9462c4dc73e17f971ec1f171d44bfffb72e65a130117233388a0ebc7ec5656f9"
dependencies = [
"crossbeam-channel",
"log",
"serde",
"serde_derive",
"serde_json",
]

View File

@ -102,7 +102,7 @@ libproc = "0.14"
log = "0.4"
lru = "0.12"
lscolors = { version = "0.17", default-features = false }
lsp-server = "0.7.5"
lsp-server = "0.7.8"
lsp-types = { version = "0.97.0", features = ["proposed"] }
lsp-textdocument = "0.4.0"
mach2 = "0.4"

View File

@ -198,7 +198,7 @@ fn try_find_id_in_def(
id_ref: Option<&Id>,
) -> Option<(Id, Span)> {
let call_name = working_set.get_span_contents(call.head);
if call_name != "def".as_bytes() && call_name != "export def".as_bytes() {
if call_name != b"def" && call_name != b"export def" {
return None;
};
let mut span = None;

View File

@ -54,37 +54,18 @@ fn find_reference_in_file(
file: &FullTextDocument,
fp: &Path,
id: &Id,
) -> Option<Vec<Range>> {
let fp_str = fp.to_str()?;
) -> Option<Vec<Span>> {
let block = parse(
working_set,
Some(fp_str),
fp.to_str(),
file.get_content(None).as_bytes(),
false,
);
let file_span = working_set.get_span_for_filename(fp_str)?;
let offset = file_span.start;
let mut references: Vec<Span> = find_reference_by_id(&block, working_set, id);
// NOTE: for arguments whose declaration is in a signature
// which is not covered in the AST
if let Id::Variable(vid) = id {
let decl_span = working_set.get_variable(*vid).declaration_span;
if file_span.contains_span(decl_span)
&& decl_span.end > decl_span.start
&& !references.contains(&decl_span)
{
references.push(decl_span);
}
}
let occurs: Vec<Range> = references
.iter()
.map(|span| span_to_range(span, file, offset))
.collect();
let references: Vec<Span> = find_reference_by_id(&block, working_set, id);
// add_block to avoid repeated parsing
working_set.add_block(block);
(!occurs.is_empty()).then_some(occurs)
(!references.is_empty()).then_some(references)
}
impl LanguageServer {
@ -284,6 +265,7 @@ impl LanguageServer {
.filter_map(|p| p.ok())
.collect();
let len = scripts.len();
let definition_span = Self::find_definition_span_by_id(&working_set, &id);
for (i, fp) in scripts.iter().enumerate() {
#[cfg(test)]
@ -324,7 +306,34 @@ impl LanguageServer {
}
&FullTextDocument::new("nu".to_string(), 0, content_string.into())
};
let _ = find_reference_in_file(&mut working_set, file, fp, &id).map(|ranges| {
let _ = find_reference_in_file(&mut working_set, file, fp, &id).map(|mut refs| {
let file_span = working_set
.get_span_for_filename(fp.to_string_lossy().as_ref())
.unwrap_or(Span::unknown());
// NOTE: for arguments whose declaration is in a signature
// which is not covered in the AST
if let (Id::Variable(_), Some(decl_span)) = (&id, definition_span) {
if file_span.contains_span(decl_span)
&& decl_span.end > decl_span.start
&& !refs.contains(&decl_span)
{
let leading_dashes = working_set
.get_span_contents(decl_span)
.iter()
// remove leading dashes for flags
.take_while(|c| *c == &b'-')
.count();
let start = decl_span.start + leading_dashes;
refs.push(Span {
start,
end: start + span.end - span.start,
});
}
}
let ranges = refs
.iter()
.map(|span| span_to_range(span, file, file_span.start))
.collect();
data_sender
.send(InternalMessage::RangeMessage(RangePerDoc { uri, ranges }))
.ok();
@ -693,7 +702,7 @@ mod tests {
"newText": "new"
},
{
"range": { "start": { "line": 1, "character": 2 }, "end": { "line": 1, "character": 7 } },
"range": { "start": { "line": 1, "character": 4 }, "end": { "line": 1, "character": 9 } },
"newText": "new"
}
]

View File

@ -1,5 +1,5 @@
export def foooo [
param: int
--param(-p): int
] {
$param
}