fix(lsp): find_id for custom def in custom def (#15289)

# Description

Enables hover/rename/references for:

```nushell
def foo [] {
  def bar [] { }
     # |____________ this custom command
}
```

# User-Facing Changes

# Tests + Formatting

+1

# After Submitting
This commit is contained in:
zc he 2025-03-12 20:35:28 +08:00 committed by GitHub
parent e926919582
commit 789781665d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 1 deletions

View File

@ -74,7 +74,17 @@ fn try_find_id_in_def(
}
let span = strip_quotes(span?, working_set);
let name = working_set.get_span_contents(span);
let decl_id = Id::Declaration(working_set.find_decl(name)?);
let decl_id = Id::Declaration(working_set.find_decl(name).or_else(|| {
// for defs inside def
// TODO: get scope by position
// https://github.com/nushell/nushell/issues/15291
(0..working_set.num_decls()).find_map(|id| {
let decl_id = nu_protocol::DeclId::new(id);
let decl = working_set.get_decl(decl_id);
let span = working_set.get_block(decl.block_id()?).span?;
call.span().contains_span(span).then_some(decl_id)
})
})?);
id_ref
.is_none_or(|id_r| decl_id == *id_r)
.then_some((decl_id, span))

View File

@ -957,6 +957,30 @@ mod tests {
);
}
#[test]
fn hover_on_custom_in_custom() {
let (client_connection, _recv) = initialize_language_server(None, None);
let mut script = fixtures();
script.push("lsp");
script.push("hover");
script.push("command.nu");
let script = path_to_uri(&script);
open_unchecked(&client_connection, script.clone());
let resp = send_hover_request(&client_connection, script.clone(), 9, 7);
assert_json_eq!(
result_from_message(resp),
serde_json::json!({
"contents": {
"kind": "markdown",
"value": "\n---\n### Usage \n```nu\n bar {flags}\n```\n\n### Flags\n\n `-h`, `--help` - Display the help message for this command\n\n"
}
})
);
}
#[test]
fn hover_on_external_command() {
let (client_connection, _recv) = initialize_language_server(None, None);

View File

@ -5,3 +5,7 @@ hello
[""] | str join
^sleep
def foo [] {
def bar [] { }
}