Skip to content

Commit 3d2b98e

Browse files
committed
test: adds missing edge case of flag name completion for lsp
1 parent 85b5e57 commit 3d2b98e

File tree

3 files changed

+32
-39
lines changed

3 files changed

+32
-39
lines changed

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

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -490,32 +490,6 @@ impl NuCompleter {
490490
}
491491
}
492492
} else if let Some(command_wide_completer) = signature.complete {
493-
let flag_completions = {
494-
let (new_span, prefix) =
495-
strip_placeholder_if_any(working_set, &span, strip);
496-
let ctx = Context::new(working_set, new_span, prefix, offset);
497-
let flag_completion_helper = || {
498-
let mut flag_completions = FlagCompletion {
499-
decl_id: call.decl_id,
500-
};
501-
self.process_completion(&mut flag_completions, &ctx)
502-
};
503-
504-
match arg {
505-
// flags
506-
Argument::Named(_) | Argument::Unknown(_)
507-
if prefix.starts_with(b"-") =>
508-
{
509-
flag_completion_helper()
510-
}
511-
// only when `strip` == false
512-
Argument::Positional(_) if prefix == b"-" => {
513-
flag_completion_helper()
514-
}
515-
_ => vec![],
516-
}
517-
};
518-
519493
let completion = match command_wide_completer {
520494
CommandWideCompleter::Command(decl_id) => {
521495
CommandWideCompletion::command(
@@ -545,14 +519,16 @@ impl NuCompleter {
545519
let ctx = Context::new(working_set, span, b"", offset);
546520
let results = self.process_completion(&mut completion, &ctx);
547521

548-
// Prioritize flag completions above everything else
549-
let flags_length = flag_completions.len();
550-
suggestions.splice(0..0, flag_completions);
551-
552522
// Prioritize external results over (sub)commands
553-
suggestions.splice(flags_length..flags_length, results);
523+
suggestions.splice(0..0, results);
554524

555-
if !completion.need_fallback {
525+
let arg_prefix = working_set.get_span_contents(span);
526+
// Still need internal flag name completions,
527+
// but not flag value completions
528+
if !(completion.need_fallback
529+
|| (arg_prefix.starts_with(b"-")
530+
&& !matches!(arg, Argument::Named((_, _, Some(val))) if val.span.contains(pos))))
531+
{
556532
return suggestions;
557533
}
558534
}
@@ -561,7 +537,7 @@ impl NuCompleter {
561537
// normal arguments completion
562538
let (new_span, prefix) = strip_placeholder_if_any(working_set, &span, strip);
563539
let ctx = Context::new(working_set, new_span, prefix, offset);
564-
let flag_completion_helper = || {
540+
let flag_completion_helper = |ctx: Context| {
565541
let mut flag_completions = FlagCompletion {
566542
decl_id: call.decl_id,
567543
};
@@ -574,15 +550,25 @@ impl NuCompleter {
574550
// flags
575551
Argument::Named((name, _, val)) if prefix.starts_with(b"-") => {
576552
match val {
577-
None => flag_completion_helper(),
553+
None => flag_completion_helper(ctx),
578554
// It's required because it's edge case of lsp completion for
579555
// flag name itself.
580556
Some(val) if !val.span.contains(pos) => {
581-
flag_completion_helper()
557+
// Span/prefix calibration
558+
let mut new_span = Span::new(span.start, val.span.start);
559+
let raw_prefix = working_set.get_span_contents(new_span);
560+
let prefix = raw_prefix.trim_ascii_end();
561+
let prefix = prefix.strip_suffix(b"=").unwrap_or(prefix);
562+
new_span.end = new_span
563+
.end
564+
.saturating_sub(raw_prefix.len() - prefix.len())
565+
.min(span.start);
566+
567+
let ctx =
568+
Context::new(working_set, new_span, prefix, offset);
569+
flag_completion_helper(ctx)
582570
}
583571
Some(_) => {
584-
// TODO: add a test to flag value completion in nu-lsp/src/completion.rs
585-
//
586572
// Completed flag value.
587573
// strip from `--foo ..a|` and `--foo=..a|` to `..a`, and also remove the place holder.
588574
// to make a user friendly completion items.
@@ -608,10 +594,12 @@ impl NuCompleter {
608594
}
609595
}
610596
Argument::Unknown(_) if prefix.starts_with(b"-") => {
611-
flag_completion_helper()
597+
flag_completion_helper(ctx)
612598
}
613599
// only when `strip` == false
614-
Argument::Positional(_) if prefix == b"-" => flag_completion_helper(),
600+
Argument::Positional(_) if prefix == b"-" => {
601+
flag_completion_helper(ctx)
602+
}
615603
// complete according to expression type and command head
616604
Argument::Positional(expr) => {
617605
let command_head = working_set.get_decl(call.decl_id).name();

crates/nu-lsp/src/completion.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,9 @@ mod tests {
443443
#[case::command_fallback("command.nu", (13, 9), None, serde_json::json!([
444444
{ "label": "config n foo bar", "detail": DETAIL_STR, "kind": 2 }
445445
]))]
446+
#[case::command_fallback("command.nu", (15, 17), None, serde_json::json!([
447+
{ "label": "-e", "detail": "byte encode endian, available options: native(default), little, big", "kind": 5 }
448+
]))]
446449
#[case::fallback_file_path("fallback.nu", (5, 4), None, serde_json::json!([
447450
{
448451
"label": "cell_path.nu",

tests/fixtures/lsp/completion/command.nu

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ def "config n foo bar" [
1212
}
1313

1414
config n # don't panic!
15+
16+
'1' | into int -e big --endian big

0 commit comments

Comments
 (0)