11use 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 ,
54} ;
65
76use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
@@ -27,48 +26,37 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
2726pub ( crate ) fn generate_derive ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
2827 let cap = ctx. config . snippet_cap ?;
2928 let nominal = ctx. find_node_at_offset :: < ast:: Adt > ( ) ?;
30- let node_start = derive_insertion_offset ( & nominal) ?;
3129 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 ( ) ) ;
6447
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+ } )
7260}
7361
7462#[ cfg( test) ]
0 commit comments