Repository: nushell/nushell
File: crates/nu-lsp/src/lib.rs (Rust)

Code before:
        engine_state.add_env_var("PWD".into(), Value::test_string(cwd.to_string_lossy()));

        let (file, path, mut working_set) = self.read_in_file(
            engine_state,
            &params.text_document_position_params.text_document.uri,
        )?;

        let (id, _, _) = Self::find_id(
            &mut working_set,
            path,
            file,
            Self::lsp_position_to_byte_offset(&params.text_document_position_params.position, file),
        )?;

        match id {
            Id::Declaration(decl_id) => {
                if let Some(block_id) = working_set.get_decl(decl_id).block_id() {
                    let block = working_set.get_block(block_id);
                    if let Some(span) = &block.span {
                        for cached_file in working_set.files() {
                            if cached_file.covered_span.contains(span.start) {
                                let uri = Url::from_file_path(&*cached_file.name).ok()?;
                                let rope_of_file = self
                                    .ropes
                                    .entry(uri.to_file_path().ok()?)
                                    .or_insert_with(|| {
                                        let raw_string =
                                            String::from_utf8_lossy(&cached_file.content);
                                        Rope::from_str(&raw_string)
                                    });
                                return Some(GotoDefinitionResponse::Scalar(Location {
                                    uri,
                                    range: Self::span_to_range(
                                        span,
                                        rope_of_file,
                                        cached_file.covered_span.start,
                                    ),
                                }));
                            }
                        }
                    }
                }
            }
            Id::Variable(var_id) => {
                let var = working_set.get_variable(var_id);
                for cached_file in working_set.files() {
                    if cached_file
                        .covered_span
                        .contains(var.declaration_span.start)
                    {
                        let uri = Url::from_file_path(&*cached_file.name).ok()?;

Review comment (refactor):
Do you have an idea how that then plays together with the [`textDocument` synchronization](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_synchronization)?

> The document’s content is now managed by the client and the server must not try to read the document’s content using the document’s Uri.

Maybe, the code shouldn't be duplicated in the match arms.

Code after:
        let contents = file.bytes().collect::<Vec<u8>>();
        let block = parse(working_set, Some(&file_path), &contents, false);
        let flattened = flatten_block(working_set, &block);

        let offset = working_set.get_span_for_filename(&file_path)?.start;
        let location = location + offset;

        for (span, shape) in flattened {
            if location >= span.start && location < span.end {
                match &shape {
                    FlatShape::Variable(var_id) | FlatShape::VarDecl(var_id) => {
                        return Some((Id::Variable(*var_id), offset, span));
                    }
                    FlatShape::InternalCall(decl_id) => {
                        return Some((Id::Declaration(*decl_id), offset, span));
                    }
                    _ => return Some((Id::Value(shape), offset, span)),
                }
            }
        }
        None
    }

    fn rope<'a, 'b: 'a>(&'b self, file_url: &Url) -> Option<(&'a Rope, &'a PathBuf)> {
        let file_path = file_url.to_file_path().ok()?;

        self.ropes
            .get_key_value(&file_path)
            .map(|(path, rope)| (rope, path))
    }

    fn read_in_file<'a>(
        &self,
        engine_state: &'a mut EngineState,
        file_url: &Url,
    ) -> Option<(&Rope, &PathBuf, StateWorkingSet<'a>)> {
        let (file, path) = self.rope(file_url)?;

        engine_state.file = Some(path.to_owned());

        let working_set = StateWorkingSet::new(engine_state);

        Some((file, path, working_set))
    }

    fn rope_file_from_cached_file(&mut self, cached_file: &CachedFile) -> Result<(Url, &Rope), ()> {
        let uri = Url::from_file_path(&*cached_file.name)?;
        let rope_of_file = self.ropes.entry(uri.to_file_path()?).or_insert_with(|| {
            let raw_string = String::from_utf8_lossy(&cached_file.content);
            Rope::from_str(&raw_string)
        });