mirror of
https://github.com/oxalica/nil.git
synced 2024-11-22 11:22:46 +03:00
Escape invalid identifiers in completions
This commit is contained in:
parent
932803b1de
commit
f3eaa77002
@ -5,7 +5,7 @@ use builtin::{BuiltinKind, ALL_BUILTINS};
|
|||||||
use either::Either::{Left, Right};
|
use either::Either::{Left, Right};
|
||||||
use smol_str::SmolStr;
|
use smol_str::SmolStr;
|
||||||
use syntax::ast::{self, AstNode, Attr};
|
use syntax::ast::{self, AstNode, Attr};
|
||||||
use syntax::semantic::AttrKind;
|
use syntax::semantic::{escape_literal_attr, is_valid_ident, AttrKind};
|
||||||
use syntax::{best_token_at_offset, match_ast, SyntaxKind, SyntaxNode, TextRange, T};
|
use syntax::{best_token_at_offset, match_ast, SyntaxKind, SyntaxNode, TextRange, T};
|
||||||
|
|
||||||
use super::hover::TY_DETAILED_DISPLAY;
|
use super::hover::TY_DETAILED_DISPLAY;
|
||||||
@ -228,6 +228,7 @@ fn complete_expr(
|
|||||||
.ancestors(scope_id)
|
.ancestors(scope_id)
|
||||||
.filter_map(|scope| scope.as_definitions())
|
.filter_map(|scope| scope.as_definitions())
|
||||||
.flatten()
|
.flatten()
|
||||||
|
.filter(|(text, _)| is_valid_ident(text))
|
||||||
.map(|(text, &name)| CompletionItem {
|
.map(|(text, &name)| CompletionItem {
|
||||||
label: text.clone(),
|
label: text.clone(),
|
||||||
source_range,
|
source_range,
|
||||||
@ -321,14 +322,17 @@ fn complete_attrpath(
|
|||||||
// We should not report current incomplete definition.
|
// We should not report current incomplete definition.
|
||||||
// This is covered by `no_incomplete_field`.
|
// This is covered by `no_incomplete_field`.
|
||||||
.filter(|name| *name != current_input)
|
.filter(|name| *name != current_input)
|
||||||
.map(|name| CompletionItem {
|
.map(|name| {
|
||||||
label: name.clone(),
|
let escaped_name = escape_literal_attr(&name);
|
||||||
source_range,
|
CompletionItem {
|
||||||
replace: name,
|
label: escaped_name.as_ref().into(),
|
||||||
kind: CompletionItemKind::LetBinding,
|
source_range,
|
||||||
signature: None,
|
replace: escaped_name.into(),
|
||||||
description: None,
|
kind: CompletionItemKind::LetBinding,
|
||||||
documentation: None,
|
signature: None,
|
||||||
|
description: None,
|
||||||
|
documentation: None,
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -373,10 +377,12 @@ fn complete_attrpath(
|
|||||||
return builtin_to_completion(source_range, name);
|
return builtin_to_completion(source_range, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let escaped_name = escape_literal_attr(name);
|
||||||
|
|
||||||
Some(CompletionItem {
|
Some(CompletionItem {
|
||||||
label: name.clone(),
|
label: escaped_name.as_ref().into(),
|
||||||
source_range,
|
source_range,
|
||||||
replace: name.clone(),
|
replace: escaped_name.into(),
|
||||||
kind: match src {
|
kind: match src {
|
||||||
AttrSource::Unknown => CompletionItemKind::Field,
|
AttrSource::Unknown => CompletionItemKind::Field,
|
||||||
AttrSource::Name(name) => module[name].kind.into(),
|
AttrSource::Name(name) => module[name].kind.into(),
|
||||||
@ -835,4 +841,19 @@ stdenv.mkDerivation {
|
|||||||
"enable",
|
"enable",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn escape_attr() {
|
||||||
|
check(
|
||||||
|
r#"{ "foo/bar" = 1; }.f$0"#,
|
||||||
|
r#""foo/bar""#,
|
||||||
|
expect![[r#"(Field) { "foo/bar" = 1; }."foo/bar""#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_invalid_ident() {
|
||||||
|
check_no(r#"let "a b" = 1; in a$0"#, "a b");
|
||||||
|
check_no(r#"let "a b" = 1; in a$0"#, r#""a b""#);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user