Skip to content

Commit 577a460

Browse files
committed
fix(lsp): completion label descriptions for cell_path and external values
1 parent 95f89a0 commit 577a460

File tree

8 files changed

+82
-54
lines changed

8 files changed

+82
-54
lines changed

crates/nu-cli/src/completions/base.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,14 @@ pub struct SemanticSuggestion {
2929
#[derive(Clone, Debug, PartialEq)]
3030
pub enum SuggestionKind {
3131
Command(nu_protocol::engine::CommandType),
32-
Type(nu_protocol::Type),
32+
Value(nu_protocol::Type),
33+
CellPath,
34+
Directory,
35+
File,
36+
Flag,
3337
Module,
3438
Operator,
39+
Variable,
3540
}
3641

3742
impl From<Suggestion> for SemanticSuggestion {

crates/nu-cli/src/completions/cell_path_completions.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,23 +108,30 @@ fn get_suggestions_by_value(
108108
value: &Value,
109109
current_span: reedline::Span,
110110
) -> Vec<SemanticSuggestion> {
111-
let kind = SuggestionKind::Type(value.get_type());
112-
let str_to_suggestion = |s: String| SemanticSuggestion {
111+
let to_suggestion = |s: String, v: Option<&Value>| SemanticSuggestion {
113112
suggestion: Suggestion {
114113
value: s,
115114
span: current_span,
115+
description: v.map(|v| v.get_type().to_string()),
116116
..Suggestion::default()
117117
},
118-
kind: Some(kind.to_owned()),
118+
kind: Some(SuggestionKind::CellPath),
119119
};
120120
match value {
121121
Value::Record { val, .. } => val
122122
.columns()
123-
.map(|s| str_to_suggestion(s.to_string()))
123+
.map(|s| to_suggestion(s.to_string(), val.get(s)))
124124
.collect(),
125125
Value::List { vals, .. } => get_columns(vals.as_slice())
126126
.into_iter()
127-
.map(str_to_suggestion)
127+
.map(|s| {
128+
to_suggestion(
129+
s.clone(),
130+
vals.first()
131+
.and_then(|v| v.as_record().ok())
132+
.and_then(|rv| rv.get(s)),
133+
)
134+
})
128135
.collect(),
129136
_ => vec![],
130137
}

crates/nu-cli/src/completions/completer.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use nu_protocol::{
1010
ast::{Argument, Block, Expr, Expression, FindMapResult, Traverse},
1111
debugger::WithoutDebug,
1212
engine::{Closure, EngineState, Stack, StateWorkingSet},
13-
PipelineData, Span, Value,
13+
PipelineData, Span, Type, Value,
1414
};
1515
use reedline::{Completer as ReedlineCompleter, Suggestion};
1616
use std::{str, sync::Arc};
@@ -639,7 +639,7 @@ pub fn map_value_completions<'a>(
639639
},
640640
..Suggestion::default()
641641
},
642-
kind: Some(SuggestionKind::Type(x.get_type())),
642+
kind: Some(SuggestionKind::Value(x.get_type())),
643643
});
644644
}
645645

@@ -653,41 +653,41 @@ pub fn map_value_completions<'a>(
653653
},
654654
..Suggestion::default()
655655
};
656+
let mut value_type = Type::String;
656657

657658
// Iterate the cols looking for `value` and `description`
658-
record.iter().for_each(|it| {
659-
// Match `value` column
660-
if it.0 == "value" {
661-
// Convert the value to string
662-
if let Ok(val_str) = it.1.coerce_string() {
663-
// Update the suggestion value
664-
suggestion.value = val_str;
659+
record.iter().for_each(|(key, value)| {
660+
match key.as_str() {
661+
"value" => {
662+
value_type = value.get_type();
663+
// Convert the value to string
664+
if let Ok(val_str) = value.coerce_string() {
665+
// Update the suggestion value
666+
suggestion.value = val_str;
667+
}
665668
}
666-
}
667-
668-
// Match `description` column
669-
if it.0 == "description" {
670-
// Convert the value to string
671-
if let Ok(desc_str) = it.1.coerce_string() {
672-
// Update the suggestion value
673-
suggestion.description = Some(desc_str);
669+
"description" => {
670+
// Convert the value to string
671+
if let Ok(desc_str) = value.coerce_string() {
672+
// Update the suggestion value
673+
suggestion.description = Some(desc_str);
674+
}
674675
}
675-
}
676-
677-
// Match `style` column
678-
if it.0 == "style" {
679-
// Convert the value to string
680-
suggestion.style = match it.1 {
681-
Value::String { val, .. } => Some(lookup_ansi_color_style(val)),
682-
Value::Record { .. } => Some(color_record_to_nustyle(it.1)),
683-
_ => None,
684-
};
676+
"style" => {
677+
// Convert the value to string
678+
suggestion.style = match value {
679+
Value::String { val, .. } => Some(lookup_ansi_color_style(val)),
680+
Value::Record { .. } => Some(color_record_to_nustyle(value)),
681+
_ => None,
682+
};
683+
}
684+
_ => (),
685685
}
686686
});
687687

688688
return Some(SemanticSuggestion {
689689
suggestion,
690-
kind: Some(SuggestionKind::Type(x.get_type())),
690+
kind: Some(SuggestionKind::Value(value_type)),
691691
});
692692
}
693693

crates/nu-cli/src/completions/directory_completions.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use nu_protocol::{
99
use reedline::Suggestion;
1010
use std::path::Path;
1111

12-
use super::{completion_common::FileSuggestion, SemanticSuggestion};
12+
use super::{completion_common::FileSuggestion, SemanticSuggestion, SuggestionKind};
1313

1414
pub struct DirectoryCompletion;
1515

@@ -47,8 +47,7 @@ impl Completer for DirectoryCompletion {
4747
},
4848
..Suggestion::default()
4949
},
50-
// TODO????
51-
kind: None,
50+
kind: Some(SuggestionKind::Directory),
5251
})
5352
.collect();
5453

crates/nu-cli/src/completions/file_completions.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use nu_protocol::{
99
use reedline::Suggestion;
1010
use std::path::Path;
1111

12-
use super::{completion_common::FileSuggestion, SemanticSuggestion};
12+
use super::{completion_common::FileSuggestion, SemanticSuggestion, SuggestionKind};
1313

1414
pub struct FileCompletion;
1515

@@ -50,8 +50,7 @@ impl Completer for FileCompletion {
5050
},
5151
..Suggestion::default()
5252
},
53-
// TODO????
54-
kind: None,
53+
kind: Some(SuggestionKind::File),
5554
})
5655
.collect();
5756

crates/nu-cli/src/completions/flag_completions.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use nu_protocol::{
55
};
66
use reedline::Suggestion;
77

8-
use super::SemanticSuggestion;
8+
use super::{SemanticSuggestion, SuggestionKind};
99

1010
#[derive(Clone)]
1111
pub struct FlagCompletion {
@@ -35,8 +35,7 @@ impl Completer for FlagCompletion {
3535
append_whitespace: true,
3636
..Suggestion::default()
3737
},
38-
// TODO????
39-
kind: None,
38+
kind: Some(SuggestionKind::Flag),
4039
});
4140
};
4241

crates/nu-cli/src/completions/variable_completions.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ impl Completer for VariableCompletion {
3232
suggestion: Suggestion {
3333
value: builtin.to_string(),
3434
span: current_span,
35+
description: Some("reserved".into()),
3536
..Suggestion::default()
3637
},
37-
// TODO is there a way to get the VarId to get the type???
38-
kind: None,
38+
kind: Some(SuggestionKind::Variable),
3939
});
4040
}
4141

@@ -44,11 +44,10 @@ impl Completer for VariableCompletion {
4444
suggestion: Suggestion {
4545
value: String::from_utf8_lossy(name).to_string(),
4646
span: current_span,
47+
description: Some(working_set.get_variable(*var_id).ty.to_string()),
4748
..Suggestion::default()
4849
},
49-
kind: Some(SuggestionKind::Type(
50-
working_set.get_variable(*var_id).ty.clone(),
51-
)),
50+
kind: Some(SuggestionKind::Variable),
5251
})
5352
};
5453

crates/nu-lsp/src/completion.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@ impl LanguageServer {
6161
.kind
6262
.clone()
6363
.map(|kind| match kind {
64-
SuggestionKind::Type(t) => t.to_string(),
64+
SuggestionKind::Value(t) => t.to_string(),
6565
SuggestionKind::Command(cmd) => cmd.to_string(),
6666
SuggestionKind::Module => "module".to_string(),
6767
SuggestionKind::Operator => "operator".to_string(),
68+
SuggestionKind::Variable => "variable".to_string(),
69+
SuggestionKind::Flag => "flag".to_string(),
70+
_ => String::new(),
6871
})
6972
.map(|s| CompletionItemLabelDetails {
7073
detail: None,
@@ -103,18 +106,23 @@ impl LanguageServer {
103106
suggestion_kind: Option<SuggestionKind>,
104107
) -> Option<CompletionItemKind> {
105108
suggestion_kind.and_then(|suggestion_kind| match suggestion_kind {
106-
SuggestionKind::Type(t) => match t {
107-
nu_protocol::Type::String => Some(CompletionItemKind::VARIABLE),
109+
SuggestionKind::Value(t) => match t {
110+
nu_protocol::Type::String => Some(CompletionItemKind::VALUE),
108111
_ => None,
109112
},
113+
SuggestionKind::CellPath => Some(CompletionItemKind::PROPERTY),
110114
SuggestionKind::Command(c) => match c {
111115
nu_protocol::engine::CommandType::Keyword => Some(CompletionItemKind::KEYWORD),
112116
nu_protocol::engine::CommandType::Builtin => Some(CompletionItemKind::FUNCTION),
113117
nu_protocol::engine::CommandType::External => Some(CompletionItemKind::INTERFACE),
114118
_ => None,
115119
},
120+
SuggestionKind::Directory => Some(CompletionItemKind::FOLDER),
121+
SuggestionKind::File => Some(CompletionItemKind::FILE),
122+
SuggestionKind::Flag => Some(CompletionItemKind::FIELD),
116123
SuggestionKind::Module => Some(CompletionItemKind::MODULE),
117124
SuggestionKind::Operator => Some(CompletionItemKind::OPERATOR),
125+
SuggestionKind::Variable => Some(CompletionItemKind::VARIABLE),
118126
})
119127
}
120128
}
@@ -180,7 +188,7 @@ mod tests {
180188
expected: serde_json::json!([
181189
{
182190
"label": "$greeting",
183-
"labelDetails": { "description": "string" },
191+
"labelDetails": { "description": "variable" },
184192
"textEdit": {
185193
"newText": "$greeting",
186194
"range": { "start": { "character": 5, "line": 2 }, "end": { "character": 9, "line": 2 } }
@@ -236,9 +244,11 @@ mod tests {
236244
&serde_json::json!({
237245
"label": "-s",
238246
"detail": "test flag",
247+
"labelDetails": { "description": "flag" },
239248
"textEdit": { "range": { "start": { "line": 1, "character": 17 }, "end": { "line": 1, "character": 18 }, },
240249
"newText": "-s"
241250
},
251+
"kind": 5
242252
})
243253
));
244254

@@ -248,9 +258,11 @@ mod tests {
248258
&serde_json::json!({
249259
"label": "--long",
250260
"detail": "test flag",
261+
"labelDetails": { "description": "flag" },
251262
"textEdit": { "range": { "start": { "line": 2, "character": 19 }, "end": { "line": 2, "character": 22 }, },
252263
"newText": "--long"
253264
},
265+
"kind": 5
254266
})
255267
));
256268

@@ -259,9 +271,11 @@ mod tests {
259271
assert!(result_from_message(resp).as_array().unwrap().contains(
260272
&serde_json::json!({
261273
"label": "LICENSE",
274+
"labelDetails": { "description": "" },
262275
"textEdit": { "range": { "start": { "line": 2, "character": 17 }, "end": { "line": 2, "character": 18 }, },
263276
"newText": "LICENSE"
264277
},
278+
"kind": 17
265279
})
266280
));
267281

@@ -271,9 +285,11 @@ mod tests {
271285
&serde_json::json!({
272286
"label": "-g",
273287
"detail": "count indexes and split using grapheme clusters (all visible chars have length 1)",
288+
"labelDetails": { "description": "flag" },
274289
"textEdit": { "range": { "start": { "line": 10, "character": 33 }, "end": { "line": 10, "character": 34 }, },
275290
"newText": "-g"
276291
},
292+
"kind": 5
277293
})
278294
));
279295
}
@@ -328,9 +344,11 @@ mod tests {
328344
assert!(result_from_message(resp).as_array().unwrap().contains(
329345
&serde_json::json!({
330346
"label": "LICENSE",
347+
"labelDetails": { "description": "" },
331348
"textEdit": { "range": { "start": { "line": 5, "character": 3 }, "end": { "line": 5, "character": 4 }, },
332349
"newText": "LICENSE"
333350
},
351+
"kind": 17
334352
})
335353
));
336354
}
@@ -411,11 +429,12 @@ mod tests {
411429
expected: serde_json::json!([
412430
{
413431
"label": "1",
414-
"labelDetails": { "description": "record<1: string, 🤔🐘: table<baz: int>>" },
432+
"detail": "string",
415433
"textEdit": {
416434
"newText": "1",
417435
"range": { "start": { "line": 1, "character": 5 }, "end": { "line": 1, "character": 5 } }
418436
},
437+
"kind": 10
419438
},
420439
])
421440
);
@@ -426,11 +445,12 @@ mod tests {
426445
expected: serde_json::json!([
427446
{
428447
"label": "baz",
429-
"labelDetails": { "description": "table<baz: int>" },
448+
"detail": "int",
430449
"textEdit": {
431450
"newText": "baz",
432451
"range": { "start": { "line": 1, "character": 10 }, "end": { "line": 1, "character": 10 } }
433452
},
453+
"kind": 10
434454
},
435455
])
436456
);

0 commit comments

Comments
 (0)