11//! Completes environment variables defined by Cargo (https://doc.rust-lang.org/cargo/reference/environment-variables.html)
2+ use ide_db:: syntax_helpers:: node_ext:: get_outer_macro_name;
3+ use syntax:: ast:: { self , IsString } ;
24
3- use syntax:: { ast, AstToken , AstNode , TextRange , TextSize } ;
4-
5- use crate :: { context:: CompletionContext , CompletionItem , CompletionItemKind } ;
5+ use crate :: { CompletionItem , CompletionItemKind } ;
66
77use super :: Completions ;
88const CARGO_DEFINED_VARS : & [ ( & str , & str ) ] = & [
@@ -29,34 +29,27 @@ const CARGO_DEFINED_VARS: &[(&str, &str)] = &[
2929
3030pub ( crate ) fn complete_cargo_env_vars (
3131 acc : & mut Completions ,
32- ctx : & CompletionContext < ' _ > ,
33- original : & ast:: String
34- ) {
35- if !is_env_macro ( original) {
36- return ;
37- }
38-
39- let start = ctx. original_token . text_range ( ) . start ( ) + TextSize :: from ( 1 ) ;
40- let cursor = ctx. position . offset ;
41-
42- CompletionItem :: new ( CompletionItemKind :: Binding , TextRange :: new ( start, cursor) , "CARGO" ) . add_to ( acc) ;
32+ expanded : & ast:: String ,
33+ ) -> Option < ( ) > {
34+ guard_env_macro ( expanded) ?;
35+ let range = expanded. text_range_between_quotes ( ) ?;
36+
37+ CARGO_DEFINED_VARS . iter ( ) . for_each ( |( var, detail) | {
38+ let mut item = CompletionItem :: new ( CompletionItemKind :: Keyword , range, * var) ;
39+ item. detail ( * detail) ;
40+ item. add_to ( acc) ;
41+ } ) ;
42+
43+ Some ( ( ) )
4344}
4445
45- fn is_env_macro ( string : & ast:: String ) -> bool {
46- //todo: replace copypaste from format_string with separate function
47- ( || {
48- let macro_call = string. syntax ( ) . parent_ancestors ( ) . find_map ( ast:: MacroCall :: cast) ?;
49- let name = macro_call. path ( ) ?. segment ( ) ?. name_ref ( ) ?;
50-
51- if !matches ! ( name. text( ) . as_str( ) ,
52- "env" | "option_env" ) {
53- return None ;
54- }
55-
46+ fn guard_env_macro ( string : & ast:: String ) -> Option < ( ) > {
47+ let name = get_outer_macro_name ( string) ?;
48+ if !matches ! ( name. text( ) . as_str( ) , "env" | "option_env" ) {
49+ return None ;
50+ }
5651
57- Some ( ( ) )
58- } ) ( )
59- . is_some ( )
52+ Some ( ( ) )
6053}
6154
6255#[ cfg( test) ]
@@ -112,4 +105,4 @@ mod tests {
112105 let completions = completion_list ( fixture) ;
113106 assert ! ( completions. is_empty( ) , "Completions weren't empty: {}" , completions) ;
114107 }
115- }
108+ }
0 commit comments