11use pgt_schema_cache:: ProcKind ;
2- use pgt_treesitter:: context:: { NodeUnderCursor , TreesitterContext , WrappingClause , WrappingNode } ;
2+ use pgt_treesitter:: context:: { TreesitterContext , WrappingClause , WrappingNode } ;
33
44use super :: CompletionRelevanceData ;
55
@@ -17,7 +17,11 @@ impl<'a> From<CompletionRelevanceData<'a>> for CompletionFilter<'a> {
1717impl CompletionFilter < ' _ > {
1818 pub fn is_relevant ( & self , ctx : & TreesitterContext ) -> Option < ( ) > {
1919 self . completable_context ( ctx) ?;
20- self . check_clause ( ctx) ?;
20+
21+ self . check_node_type ( ctx)
22+ // we want to rely on treesitter more, so checking the clause is a fallback
23+ . or_else ( || self . check_clause ( ctx) ) ?;
24+
2125 self . check_invocation ( ctx) ?;
2226 self . check_mentioned_schema_or_alias ( ctx) ?;
2327
@@ -67,30 +71,42 @@ impl CompletionFilter<'_> {
6771 }
6872
6973 // No autocompletions if there are two identifiers without a separator.
70- if ctx. node_under_cursor . as_ref ( ) . is_some_and ( |n| match n {
71- NodeUnderCursor :: TsNode ( node) => node. prev_sibling ( ) . is_some_and ( |p| {
72- ( p. kind ( ) == "identifier" || p. kind ( ) == "object_reference" )
73- && n. kind ( ) == "identifier"
74- } ) ,
75- NodeUnderCursor :: CustomNode { .. } => false ,
74+ if ctx. node_under_cursor . as_ref ( ) . is_some_and ( |node| {
75+ node. prev_sibling ( ) . is_some_and ( |p| {
76+ ( p. kind ( ) == "any_identifier" || p. kind ( ) == "object_reference" )
77+ && node. kind ( ) == "any_identifier"
78+ } )
7679 } ) {
7780 return None ;
7881 }
7982
8083 // no completions if we're right after an asterisk:
8184 // `select * {}`
82- if ctx. node_under_cursor . as_ref ( ) . is_some_and ( |n| match n {
83- NodeUnderCursor :: TsNode ( node) => node
84- . prev_sibling ( )
85- . is_some_and ( |p| ( p. kind ( ) == "all_fields" ) && n. kind ( ) == "identifier" ) ,
86- NodeUnderCursor :: CustomNode { .. } => false ,
85+ if ctx. node_under_cursor . as_ref ( ) . is_some_and ( |node| {
86+ node. prev_sibling ( )
87+ . is_some_and ( |p| ( p. kind ( ) == "all_fields" ) && node. kind ( ) == "any_identifier" )
8788 } ) {
8889 return None ;
8990 }
9091
9192 Some ( ( ) )
9293 }
9394
95+ fn check_node_type ( & self , ctx : & TreesitterContext ) -> Option < ( ) > {
96+ let kind = ctx. node_under_cursor . as_ref ( ) . map ( |n| n. kind ( ) ) ?;
97+
98+ let is_allowed = match kind {
99+ "column_identifier" => {
100+ matches ! ( self . data, CompletionRelevanceData :: Column ( _) )
101+ && !ctx. matches_ancestor_history ( & [ "insert_values" , "field" ] )
102+ && !ctx. node_under_cursor_is_within_field_name ( "binary_expr_right" )
103+ }
104+ _ => false ,
105+ } ;
106+
107+ if is_allowed { Some ( ( ) ) } else { None }
108+ }
109+
94110 fn check_clause ( & self , ctx : & TreesitterContext ) -> Option < ( ) > {
95111 ctx. wrapping_clause_type
96112 . as_ref ( )
@@ -99,9 +115,8 @@ impl CompletionFilter<'_> {
99115 CompletionRelevanceData :: Table ( _) => match clause {
100116 WrappingClause :: From | WrappingClause :: Update => true ,
101117
102- WrappingClause :: RevokeStatement => {
103- ctx. matches_ancestor_history ( & [ "revoke_on_table" , "object_reference" ] )
104- }
118+ WrappingClause :: RevokeStatement | WrappingClause :: GrantStatement => ctx
119+ . matches_ancestor_history ( & [ "grantable_on_table" , "object_reference" ] ) ,
105120
106121 WrappingClause :: Join { on_node : None } => true ,
107122 WrappingClause :: Join { on_node : Some ( on) } => ctx
@@ -206,10 +221,12 @@ impl CompletionFilter<'_> {
206221 | WrappingClause :: Update
207222 | WrappingClause :: Delete => true ,
208223
209- WrappingClause :: RevokeStatement => {
210- ( ctx. matches_ancestor_history ( & [ "revoke_on_table" , "object_reference" ] )
211- && ctx. schema_or_alias_name . is_none ( ) )
212- || ctx. matches_ancestor_history ( & [ "revoke_on_all" ] )
224+ WrappingClause :: RevokeStatement | WrappingClause :: GrantStatement => {
225+ ( ctx. matches_ancestor_history ( & [
226+ "grantable_on_table" ,
227+ "object_reference" ,
228+ ] ) && ctx. schema_or_alias_name . is_none ( ) )
229+ || ctx. matches_ancestor_history ( & [ "grantable_on_all" ] )
213230 }
214231
215232 WrappingClause :: Where => {
@@ -248,18 +265,17 @@ impl CompletionFilter<'_> {
248265 }
249266
250267 CompletionRelevanceData :: Role ( _) => match clause {
251- WrappingClause :: DropRole
252- | WrappingClause :: AlterRole
253- | WrappingClause :: ToRoleAssignment => true ,
268+ WrappingClause :: DropRole | WrappingClause :: AlterRole => true ,
254269
255270 WrappingClause :: SetStatement => ctx
256271 . before_cursor_matches_kind ( & [ "keyword_role" , "keyword_authorization" ] ) ,
257272
258- WrappingClause :: RevokeStatement => {
273+ WrappingClause :: RevokeStatement | WrappingClause :: GrantStatement => {
259274 ctx. matches_ancestor_history ( & [ "role_specification" ] )
260275 || ctx. node_under_cursor . as_ref ( ) . is_some_and ( |k| {
261- k. kind ( ) == "identifier "
276+ k. kind ( ) == "any_identifier "
262277 && ctx. before_cursor_matches_kind ( & [
278+ "keyword_grant" ,
263279 "keyword_revoke" ,
264280 "keyword_for" ,
265281 ] )
0 commit comments