Skip to content

Commit 6e04433

Browse files
committed
fix(lsp): more accurate PWD: from env -> parent dir of current file
1 parent a23e96c commit 6e04433

File tree

10 files changed

+37
-33
lines changed

10 files changed

+37
-33
lines changed

crates/nu-lsp/src/completion.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl LanguageServer {
2929
.is_some_and(|c| c.is_whitespace() || "|(){}[]<>,:;".contains(c));
3030

3131
self.need_parse |= need_fallback;
32-
let engine_state = Arc::new(self.new_engine_state());
32+
let engine_state = Arc::new(self.new_engine_state(Some(&path_uri)));
3333
let completer = NuCompleter::new(engine_state.clone(), Arc::new(Stack::new()));
3434
let results = if need_fallback {
3535
completer.fetch_completions_at(&file_text[..location], location)
@@ -264,10 +264,10 @@ mod tests {
264264
let resp = send_complete_request(&client_connection, script.clone(), 2, 18);
265265
assert!(result_from_message(resp).as_array().unwrap().contains(
266266
&serde_json::json!({
267-
"label": "LICENSE",
267+
"label": "command.nu",
268268
"labelDetails": { "description": "" },
269269
"textEdit": { "range": { "start": { "line": 2, "character": 17 }, "end": { "line": 2, "character": 18 }, },
270-
"newText": "LICENSE"
270+
"newText": "command.nu"
271271
},
272272
"kind": 17
273273
})
@@ -337,10 +337,10 @@ mod tests {
337337
let resp = send_complete_request(&client_connection, script, 5, 4);
338338
assert!(result_from_message(resp).as_array().unwrap().contains(
339339
&serde_json::json!({
340-
"label": "LICENSE",
340+
"label": "cell_path.nu",
341341
"labelDetails": { "description": "" },
342342
"textEdit": { "range": { "start": { "line": 5, "character": 3 }, "end": { "line": 5, "character": 4 }, },
343-
"newText": "LICENSE"
343+
"newText": "cell_path.nu"
344344
},
345345
"kind": 17
346346
})

crates/nu-lsp/src/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use miette::{miette, IntoDiagnostic, Result};
77

88
impl LanguageServer {
99
pub(crate) fn publish_diagnostics_for_file(&mut self, uri: Uri) -> Result<()> {
10-
let mut engine_state = self.new_engine_state();
10+
let mut engine_state = self.new_engine_state(Some(&uri));
1111
engine_state.generate_nu_constant();
1212

1313
let Some((_, span, working_set)) = self.parse_file(&mut engine_state, &uri, true) else {

crates/nu-lsp/src/goto.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,12 @@ impl LanguageServer {
7777
&mut self,
7878
params: &GotoDefinitionParams,
7979
) -> Option<GotoDefinitionResponse> {
80-
let mut engine_state = self.new_engine_state();
81-
8280
let path_uri = params
8381
.text_document_position_params
8482
.text_document
8583
.uri
8684
.to_owned();
85+
let mut engine_state = self.new_engine_state(Some(&path_uri));
8786
let (working_set, id, _, _) = self
8887
.parse_and_find(
8988
&mut engine_state,

crates/nu-lsp/src/hover.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,12 @@ impl LanguageServer {
129129
}
130130

131131
pub(crate) fn hover(&mut self, params: &HoverParams) -> Option<Hover> {
132-
let mut engine_state = self.new_engine_state();
133-
134132
let path_uri = params
135133
.text_document_position_params
136134
.text_document
137135
.uri
138136
.to_owned();
137+
let mut engine_state = self.new_engine_state(Some(&path_uri));
139138
let (working_set, id, _, _) = self
140139
.parse_and_find(
141140
&mut engine_state,

crates/nu-lsp/src/lib.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use miette::{miette, IntoDiagnostic, Result};
1313
use nu_protocol::{
1414
ast::{Block, PathMember},
1515
engine::{EngineState, StateDelta, StateWorkingSet},
16-
DeclId, ModuleId, Span, Type, VarId,
16+
DeclId, ModuleId, Span, Type, Value, VarId,
1717
};
1818
use std::{
1919
collections::BTreeMap,
@@ -315,13 +315,26 @@ impl LanguageServer {
315315
Ok(reset)
316316
}
317317

318-
pub(crate) fn new_engine_state(&self) -> EngineState {
318+
/// Create a clone of the initial_engine_state with:
319+
///
320+
/// * PWD set to the parent directory of given uri. Fallback to `$env.PWD` if None.
321+
/// * `StateDelta` cache merged
322+
pub(crate) fn new_engine_state(&self, uri: Option<&Uri>) -> EngineState {
319323
let mut engine_state = self.initial_engine_state.clone();
320-
let cwd = std::env::current_dir().expect("Could not get current working directory.");
321-
engine_state.add_env_var(
322-
"PWD".into(),
323-
nu_protocol::Value::test_string(cwd.to_string_lossy()),
324-
);
324+
match uri {
325+
Some(uri) => {
326+
let path = uri_to_path(uri);
327+
if let Some(path) = path.parent() {
328+
engine_state
329+
.add_env_var("PWD".into(), Value::test_string(path.to_string_lossy()))
330+
};
331+
}
332+
None => {
333+
let cwd =
334+
std::env::current_dir().expect("Could not get current working directory.");
335+
engine_state.add_env_var("PWD".into(), Value::test_string(cwd.to_string_lossy()));
336+
}
337+
}
325338
// merge the cached `StateDelta` if text not changed
326339
if !self.need_parse {
327340
engine_state
@@ -458,10 +471,7 @@ mod tests {
458471
engine_state.generate_nu_constant();
459472
assert!(load_standard_library(&mut engine_state).is_ok());
460473
let cwd = std::env::current_dir().expect("Could not get current working directory.");
461-
engine_state.add_env_var(
462-
"PWD".into(),
463-
nu_protocol::Value::test_string(cwd.to_string_lossy()),
464-
);
474+
engine_state.add_env_var("PWD".into(), Value::test_string(cwd.to_string_lossy()));
465475
if let Some(code) = nu_config_code {
466476
assert!(merge_input(code.as_bytes(), &mut engine_state, &mut Stack::new()).is_ok());
467477
}

crates/nu-lsp/src/signature.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl LanguageServer {
7878
let file_text = file.get_content(None).to_owned();
7979
drop(docs);
8080

81-
let engine_state = self.new_engine_state();
81+
let engine_state = self.new_engine_state(Some(&path_uri));
8282
let mut working_set = StateWorkingSet::new(&engine_state);
8383

8484
// NOTE: in case the cursor is at the end of the call expression

crates/nu-lsp/src/symbols.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ impl LanguageServer {
270270
&mut self,
271271
params: &DocumentSymbolParams,
272272
) -> Option<DocumentSymbolResponse> {
273-
let engine_state = self.new_engine_state();
274273
let uri = params.text_document.uri.to_owned();
274+
let engine_state = self.new_engine_state(Some(&uri));
275275
let docs = self.docs.lock().ok()?;
276276
self.symbol_cache.update(&uri, &engine_state, &docs);
277277
self.symbol_cache
@@ -284,7 +284,7 @@ impl LanguageServer {
284284
params: &WorkspaceSymbolParams,
285285
) -> Option<WorkspaceSymbolResponse> {
286286
if self.symbol_cache.any_dirty() {
287-
let engine_state = self.new_engine_state();
287+
let engine_state = self.new_engine_state(None);
288288
let docs = self.docs.lock().ok()?;
289289
self.symbol_cache.update_all(&engine_state, &docs);
290290
}

crates/nu-lsp/src/workspace.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ impl LanguageServer {
6666
&mut self,
6767
params: &DocumentHighlightParams,
6868
) -> Option<Vec<DocumentHighlight>> {
69-
let mut engine_state = self.new_engine_state();
7069
let path_uri = params
7170
.text_document_position_params
7271
.text_document
7372
.uri
7473
.to_owned();
74+
let mut engine_state = self.new_engine_state(Some(&path_uri));
7575
let (block, file_span, working_set) =
7676
self.parse_file(&mut engine_state, &path_uri, false)?;
7777
let docs = &self.docs.lock().ok()?;
@@ -137,17 +137,15 @@ impl LanguageServer {
137137
timeout: u128,
138138
) -> Option<Vec<Location>> {
139139
self.occurrences = BTreeMap::new();
140-
let mut engine_state = self.new_engine_state();
141140
let path_uri = params.text_document_position.text_document.uri.to_owned();
141+
let mut engine_state = self.new_engine_state(None);
142142
let (_, id, span, _) = self
143143
.parse_and_find(
144144
&mut engine_state,
145145
&path_uri,
146146
params.text_document_position.position,
147147
)
148148
.ok()?;
149-
// have to clone it again in order to move to another thread
150-
let engine_state = self.new_engine_state();
151149
let current_workspace_folder = self.get_workspace_folder_by_uri(&path_uri)?;
152150
let token = params
153151
.work_done_progress_params
@@ -200,8 +198,8 @@ impl LanguageServer {
200198
serde_json::from_value(request.params).into_diagnostic()?;
201199
self.occurrences = BTreeMap::new();
202200

203-
let mut engine_state = self.new_engine_state();
204201
let path_uri = params.text_document.uri.to_owned();
202+
let mut engine_state = self.new_engine_state(None);
205203

206204
let (working_set, id, span, file_offset) =
207205
self.parse_and_find(&mut engine_state, &path_uri, params.position)?;
@@ -233,8 +231,6 @@ impl LanguageServer {
233231
}))
234232
.into_diagnostic()?;
235233

236-
// have to clone it again in order to move to another thread
237-
let engine_state = self.new_engine_state();
238234
let current_workspace_folder = self
239235
.get_workspace_folder_by_uri(&path_uri)
240236
.ok_or_else(|| miette!("\nCurrent file is not in any workspace"))?;

tests/fixtures/lsp/completion/command.nu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
config n
22
config n foo bar -
3-
config n foo bar l --l
3+
config n foo bar c --l
44

55
# detail
66
def "config n foo bar" [

tests/fixtures/lsp/completion/fallback.nu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ let greeting = "Hello"
33
echo $gre
44
| st
55

6-
ls l
6+
ls c
77

88
$greeting not-h

0 commit comments

Comments
 (0)