@@ -24,6 +24,13 @@ impl CompletionFilter<'_> {
24
24
}
25
25
26
26
fn completable_context ( & self , ctx : & CompletionContext ) -> Option < ( ) > {
27
+ if ctx. wrapping_node_kind . is_none ( )
28
+ && ctx. wrapping_clause_type . is_none ( )
29
+ && ctx. is_in_error_node
30
+ {
31
+ return None ;
32
+ }
33
+
27
34
let current_node_kind = ctx. node_under_cursor . map ( |n| n. kind ( ) ) . unwrap_or ( "" ) ;
28
35
29
36
if current_node_kind. starts_with ( "keyword_" )
@@ -58,44 +65,53 @@ impl CompletionFilter<'_> {
58
65
}
59
66
60
67
fn check_clause ( & self , ctx : & CompletionContext ) -> Option < ( ) > {
61
- let clause = ctx. wrapping_clause_type . as_ref ( ) ;
62
-
63
- match self . data {
64
- CompletionRelevanceData :: Table ( _) => {
65
- let in_select_clause = clause. is_some_and ( |c| c == & WrappingClause :: Select ) ;
66
- let in_where_clause = clause. is_some_and ( |c| c == & WrappingClause :: Where ) ;
67
-
68
- if in_select_clause || in_where_clause {
69
- return None ;
70
- } ;
71
- }
72
- CompletionRelevanceData :: Column ( _) => {
73
- let in_from_clause = clause. is_some_and ( |c| c == & WrappingClause :: From ) ;
74
- if in_from_clause {
75
- return None ;
76
- }
77
-
78
- // We can complete columns in JOIN cluases, but only if we are after the
79
- // ON node in the "ON u.id = posts.user_id" part.
80
- let in_join_clause_before_on_node = clause. is_some_and ( |c| match c {
81
- // we are in a JOIN, but definitely not after an ON
82
- WrappingClause :: Join { on_node : None } => true ,
83
-
84
- WrappingClause :: Join { on_node : Some ( on) } => ctx
85
- . node_under_cursor
86
- . is_some_and ( |n| n. end_byte ( ) < on. start_byte ( ) ) ,
87
-
88
- _ => false ,
89
- } ) ;
90
-
91
- if in_join_clause_before_on_node {
92
- return None ;
68
+ ctx. wrapping_clause_type
69
+ . as_ref ( )
70
+ . map ( |clause| {
71
+ match self . data {
72
+ CompletionRelevanceData :: Table ( _) => match clause {
73
+ WrappingClause :: Select
74
+ | WrappingClause :: Where
75
+ | WrappingClause :: ColumnDefinitions => false ,
76
+ _ => true ,
77
+ } ,
78
+ CompletionRelevanceData :: Column ( _) => {
79
+ match clause {
80
+ WrappingClause :: From | WrappingClause :: ColumnDefinitions => false ,
81
+
82
+ // We can complete columns in JOIN cluases, but only if we are after the
83
+ // ON node in the "ON u.id = posts.user_id" part.
84
+ WrappingClause :: Join { on_node : Some ( on) } => ctx
85
+ . node_under_cursor
86
+ . is_some_and ( |cn| cn. start_byte ( ) >= on. end_byte ( ) ) ,
87
+
88
+ // we are in a JOIN, but definitely not after an ON
89
+ WrappingClause :: Join { on_node : None } => false ,
90
+
91
+ _ => true ,
92
+ }
93
+ }
94
+ CompletionRelevanceData :: Function ( _) => match clause {
95
+ WrappingClause :: From
96
+ | WrappingClause :: Select
97
+ | WrappingClause :: Where
98
+ | WrappingClause :: Join { .. } => true ,
99
+
100
+ _ => false ,
101
+ } ,
102
+ CompletionRelevanceData :: Schema ( _) => match clause {
103
+ WrappingClause :: Select
104
+ | WrappingClause :: Where
105
+ | WrappingClause :: From
106
+ | WrappingClause :: Join { .. }
107
+ | WrappingClause :: Update
108
+ | WrappingClause :: Delete => true ,
109
+
110
+ WrappingClause :: ColumnDefinitions => false ,
111
+ } ,
93
112
}
94
- }
95
- _ => { }
96
- }
97
-
98
- Some ( ( ) )
113
+ } )
114
+ . and_then ( |is_ok| if is_ok { Some ( ( ) ) } else { None } )
99
115
}
100
116
101
117
fn check_invocation ( & self , ctx : & CompletionContext ) -> Option < ( ) > {
@@ -170,4 +186,15 @@ mod tests {
170
186
)
171
187
. await ;
172
188
}
189
+
190
+ #[ tokio:: test]
191
+ async fn completion_after_create_table ( ) {
192
+ assert_no_complete_results ( format ! ( "create table {}" , CURSOR_POS ) . as_str ( ) , "" ) . await ;
193
+ }
194
+
195
+ #[ tokio:: test]
196
+ async fn completion_in_column_definitions ( ) {
197
+ let query = format ! ( r#"create table instruments ( {} )"# , CURSOR_POS ) ;
198
+ assert_no_complete_results ( query. as_str ( ) , "" ) . await ;
199
+ }
173
200
}
0 commit comments