1
1
use syntax:: {
2
- ast:: { self , edit:: IndentLevel , AstNode , HasAttrs } ,
3
- SyntaxKind :: { COMMENT , WHITESPACE } ,
4
- TextSize ,
2
+ ast:: { self , edit_in_place:: AttrsOwnerEdit , make, AstNode , HasAttrs } ,
3
+ T ,
5
4
} ;
6
5
7
6
use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
@@ -27,48 +26,37 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
27
26
pub ( crate ) fn generate_derive ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
28
27
let cap = ctx. config . snippet_cap ?;
29
28
let nominal = ctx. find_node_at_offset :: < ast:: Adt > ( ) ?;
30
- let node_start = derive_insertion_offset ( & nominal) ?;
31
29
let target = nominal. syntax ( ) . text_range ( ) ;
32
- acc. add (
33
- AssistId ( "generate_derive" , AssistKind :: Generate ) ,
34
- "Add `#[derive]`" ,
35
- target,
36
- |builder| {
37
- let derive_attr = nominal
38
- . attrs ( )
39
- . filter_map ( |x| x. as_simple_call ( ) )
40
- . filter ( |( name, _arg) | name == "derive" )
41
- . map ( |( _name, arg) | arg)
42
- . next ( ) ;
43
- match derive_attr {
44
- None => {
45
- let indent_level = IndentLevel :: from_node ( nominal. syntax ( ) ) ;
46
- builder. insert_snippet (
47
- cap,
48
- node_start,
49
- format ! ( "#[derive($0)]\n {indent_level}" ) ,
50
- ) ;
51
- }
52
- Some ( tt) => {
53
- // Just move the cursor.
54
- builder. insert_snippet (
55
- cap,
56
- tt. syntax ( ) . text_range ( ) . end ( ) - TextSize :: of ( ')' ) ,
57
- "$0" ,
58
- )
59
- }
60
- } ;
61
- } ,
62
- )
63
- }
30
+ acc. add ( AssistId ( "generate_derive" , AssistKind :: Generate ) , "Add `#[derive]`" , target, |edit| {
31
+ let derive_attr = nominal
32
+ . attrs ( )
33
+ . filter_map ( |x| x. as_simple_call ( ) )
34
+ . filter ( |( name, _arg) | name == "derive" )
35
+ . map ( |( _name, arg) | arg)
36
+ . next ( ) ;
37
+ match derive_attr {
38
+ None => {
39
+ let derive = make:: attr_outer ( make:: meta_token_tree (
40
+ make:: ext:: ident_path ( "derive" ) ,
41
+ make:: token_tree ( T ! [ '(' ] , vec ! [ ] ) . clone_for_update ( ) ,
42
+ ) )
43
+ . clone_for_update ( ) ;
44
+
45
+ let nominal = edit. make_mut ( nominal) ;
46
+ nominal. add_attr ( derive. clone ( ) ) ;
64
47
65
- // Insert `derive` after doc comments.
66
- fn derive_insertion_offset ( nominal : & ast:: Adt ) -> Option < TextSize > {
67
- let non_ws_child = nominal
68
- . syntax ( )
69
- . children_with_tokens ( )
70
- . find ( |it| it. kind ( ) != COMMENT && it. kind ( ) != WHITESPACE ) ?;
71
- Some ( non_ws_child. text_range ( ) . start ( ) )
48
+ edit. add_tabstop_before_token (
49
+ cap,
50
+ derive. meta ( ) . unwrap ( ) . token_tree ( ) . unwrap ( ) . r_paren_token ( ) . unwrap ( ) ,
51
+ ) ;
52
+ }
53
+ Some ( tt) => {
54
+ // Just move the cursor.
55
+ let tt = edit. make_mut ( tt) ;
56
+ edit. add_tabstop_before_token ( cap, tt. r_paren_token ( ) . unwrap ( ) ) ;
57
+ }
58
+ } ;
59
+ } )
72
60
}
73
61
74
62
#[ cfg( test) ]
0 commit comments