@@ -8,7 +8,7 @@ use nu_protocol::{
88 engine:: { Stack , StateWorkingSet , VirtualPath } ,
99} ;
1010use reedline:: Suggestion ;
11- use std:: collections:: HashSet ;
11+ use std:: collections:: { HashMap , HashSet } ;
1212
1313use super :: completion_common:: { complete_item, surround_remove} ;
1414
@@ -27,6 +27,76 @@ impl Completer for DotNuCompletion {
2727 offset : usize ,
2828 options : & CompletionOptions ,
2929 ) -> Vec < SemanticSuggestion > {
30+ let reedline_span = reedline:: Span {
31+ start : span. start - offset,
32+ end : span. end - offset,
33+ } ;
34+ // Modules that are already loaded go first
35+ let mut matcher = NuMatcher :: new ( & prefix, options, true ) ;
36+ let mut modules_map = HashMap :: new ( ) ;
37+ // TODO: inline-defined modules, e.g. `module foo {}; use foo<tab>` ?
38+ for overlay_frame in working_set. permanent_state . active_overlays ( & [ ] ) {
39+ modules_map. extend ( & overlay_frame. modules ) ;
40+ }
41+
42+ for ( module_name_bytes, module_id) in modules_map. into_iter ( ) {
43+ let value = String :: from_utf8_lossy ( module_name_bytes) . to_string ( ) ;
44+ let description = working_set. get_module_comments ( * module_id) . map ( |spans| {
45+ spans
46+ . iter ( )
47+ . map ( |sp| String :: from_utf8_lossy ( working_set. get_span_contents ( * sp) ) . into ( ) )
48+ . collect :: < Vec < String > > ( )
49+ . join ( "\n " )
50+ } ) ;
51+
52+ matcher. add_semantic_suggestion ( SemanticSuggestion {
53+ suggestion : Suggestion {
54+ value,
55+ description,
56+ span : reedline_span,
57+ append_whitespace : true ,
58+ ..Suggestion :: default ( )
59+ } ,
60+ kind : Some ( SuggestionKind :: Module ) ,
61+ } ) ;
62+ }
63+
64+ // Add std virtual paths first
65+ if self . std_virtual_path {
66+ // Where we have '/' in the prefix, e.g. use std/l
67+ if let Some ( ( base_dir, _) ) = prefix. as_ref ( ) . rsplit_once ( "/" ) {
68+ let base_dir = surround_remove ( base_dir) ;
69+ if let Some ( VirtualPath :: Dir ( sub_paths) ) = working_set. find_virtual_path ( & base_dir)
70+ {
71+ for sub_vp_id in sub_paths {
72+ let ( path, sub_vp) = working_set. get_virtual_path ( * sub_vp_id) ;
73+ matcher. add_semantic_suggestion ( SemanticSuggestion {
74+ suggestion : Suggestion {
75+ value : path. into ( ) ,
76+ span : reedline_span,
77+ append_whitespace : !matches ! ( sub_vp, VirtualPath :: Dir ( _) ) ,
78+ ..Suggestion :: default ( )
79+ } ,
80+ kind : Some ( SuggestionKind :: Module ) ,
81+ } ) ;
82+ }
83+ }
84+ } else {
85+ for path in [ "std" , "std-rfc" ] {
86+ matcher. add_semantic_suggestion ( SemanticSuggestion {
87+ suggestion : Suggestion {
88+ value : path. into ( ) ,
89+ span : reedline_span,
90+ ..Suggestion :: default ( )
91+ } ,
92+ kind : Some ( SuggestionKind :: Module ) ,
93+ } ) ;
94+ }
95+ }
96+ }
97+
98+ let mut all_results = matcher. suggestion_results ( ) ;
99+
30100 // Fetch the lib dirs
31101 // NOTE: 2 ways to setup `NU_LIB_DIRS`
32102 // 1. `const NU_LIB_DIRS = [paths]`, equal to `nu -I paths`
@@ -51,53 +121,8 @@ impl Completer for DotNuCompletion {
51121 search_dirs. insert ( cwd. into_std_path_buf ( ) ) ;
52122 }
53123
54- let mut completions = Vec :: new ( ) ;
55-
56- // Add std virtual paths first
57- if self . std_virtual_path {
58- let mut matcher = NuMatcher :: new ( & prefix, options, true ) ;
59- // Where we have '/' in the prefix, e.g. use std/l
60- if let Some ( ( base_dir, _) ) = prefix. as_ref ( ) . rsplit_once ( "/" ) {
61- let base_dir = surround_remove ( base_dir) ;
62- if let Some ( VirtualPath :: Dir ( sub_paths) ) = working_set. find_virtual_path ( & base_dir)
63- {
64- for sub_vp_id in sub_paths {
65- let ( path, sub_vp) = working_set. get_virtual_path ( * sub_vp_id) ;
66- matcher. add (
67- path. clone ( ) ,
68- FileSuggestion {
69- path : path. into ( ) ,
70- span,
71- style : None ,
72- is_dir : matches ! ( sub_vp, VirtualPath :: Dir ( _) ) ,
73- } ,
74- ) ;
75- }
76- }
77- } else {
78- for path in [ "std" , "std-rfc" ] {
79- matcher. add (
80- path,
81- FileSuggestion {
82- path : path. into ( ) ,
83- span,
84- style : None ,
85- is_dir : true ,
86- } ,
87- ) ;
88- }
89- }
90- completions. extend (
91- matcher
92- . results ( )
93- . into_iter ( )
94- . map ( |( s, _) | s)
95- . collect :: < Vec < _ > > ( ) ,
96- ) ;
97- }
98-
99124 // Fetch the files
100- completions . extend ( complete_item (
125+ let module_file_results = complete_item (
101126 false ,
102127 span,
103128 prefix. as_ref ( ) ,
@@ -108,34 +133,33 @@ impl Completer for DotNuCompletion {
108133 options,
109134 working_set. permanent_state ,
110135 stack,
111- ) ) ;
136+ ) ;
112137
113- let into_suggestion = |x : & FileSuggestion | SemanticSuggestion {
114- suggestion : Suggestion {
115- value : x. path . to_string ( ) ,
116- style : x. style ,
117- span : reedline:: Span {
118- start : x. span . start - offset,
119- end : x. span . end - offset,
120- } ,
121- append_whitespace : !x. is_dir ,
122- ..Suggestion :: default ( )
123- } ,
124- kind : Some ( SuggestionKind :: Module ) ,
125- } ;
138+ all_results. extend (
139+ // Put files atop
140+ module_file_results
141+ . iter ( )
142+ // filtering the files that ends with .nu
143+ . filter ( |it| {
144+ // for paths with spaces in them
145+ let path = it. path . trim_end_matches ( '`' ) ;
146+ path. ends_with ( ".nu" )
147+ } )
148+ // or directories
149+ . chain ( module_file_results. iter ( ) . filter ( |it| it. is_dir ) )
150+ . map ( |x : & FileSuggestion | SemanticSuggestion {
151+ suggestion : Suggestion {
152+ value : x. path . to_string ( ) ,
153+ style : x. style ,
154+ span : reedline_span,
155+ append_whitespace : !x. is_dir ,
156+ ..Suggestion :: default ( )
157+ } ,
158+ kind : Some ( SuggestionKind :: Module ) ,
159+ } )
160+ . collect :: < Vec < _ > > ( ) ,
161+ ) ;
126162
127- // Put files atop
128- completions
129- . iter ( )
130- // filtering the files that ends with .nu
131- . filter ( |it| {
132- // for paths with spaces in them
133- let path = it. path . trim_end_matches ( '`' ) ;
134- path. ends_with ( ".nu" )
135- } )
136- // or directories
137- . chain ( completions. iter ( ) . filter ( |it| it. is_dir ) )
138- . map ( into_suggestion)
139- . collect :: < Vec < _ > > ( )
163+ all_results
140164 }
141165}
0 commit comments