@@ -8,7 +8,7 @@ use lsp_types::{
88 InitializeResult , OneOf , Range , ServerCapabilities , ServerInfo , TextDocumentSyncCapability ,
99 TextDocumentSyncKind , TextEdit , Uri , WorkspaceFolder ,
1010} ;
11- use serde:: Deserialize ;
11+ use serde:: { Deserialize , Serialize } ;
1212use similar:: { DiffOp , TextDiff } ;
1313use stylua_lib:: { format_code, IndentType , OutputVerification } ;
1414
@@ -258,7 +258,7 @@ impl LanguageServer<'_> {
258258 }
259259}
260260
261- #[ derive( Deserialize , Default ) ]
261+ #[ derive( Serialize , Deserialize , Default ) ]
262262#[ serde( default ) ]
263263struct InitializationOptions {
264264 respect_editor_formatting_options : Option < bool > ,
@@ -344,23 +344,24 @@ mod tests {
344344
345345 use clap:: Parser ;
346346 use crossbeam_channel:: Receiver ;
347- use lsp_server:: Connection ;
348347
349- use lsp_server:: { ErrorCode , Message , Notification , Request , RequestId , Response } ;
348+ use lsp_server:: { Connection , ErrorCode , Message , Notification , Request , RequestId , Response } ;
350349 use lsp_types:: {
351350 notification:: { DidOpenTextDocument , Exit , Initialized , Notification as NotificationType } ,
352351 request:: { Formatting , Initialize , RangeFormatting , Request as RequestType , Shutdown } ,
353352 DidOpenTextDocumentParams , DocumentFormattingParams , DocumentRangeFormattingParams ,
354- FormattingOptions , InitializeParams , Position , Range , TextDocumentIdentifier ,
355- TextDocumentItem , TextEdit , Uri , WorkDoneProgressParams ,
356- } ;
357- use lsp_types:: {
358- OneOf , ServerCapabilities , ServerInfo , TextDocumentSyncCapability , TextDocumentSyncKind ,
353+ FormattingOptions , InitializeParams , OneOf , Position , Range , ServerCapabilities ,
354+ ServerInfo , TextDocumentIdentifier , TextDocumentItem , TextDocumentSyncCapability ,
355+ TextDocumentSyncKind , TextEdit , Uri , WorkDoneProgressParams ,
359356 } ;
360357 use serde:: de:: DeserializeOwned ;
361358 use serde_json:: to_value;
362359
363- use crate :: { config:: ConfigResolver , lsp:: main_loop, opt:: Opt } ;
360+ use crate :: {
361+ config:: ConfigResolver ,
362+ lsp:: { main_loop, InitializationOptions } ,
363+ opt:: Opt ,
364+ } ;
364365
365366 use assert_fs:: prelude:: * ;
366367
@@ -386,7 +387,7 @@ mod tests {
386387 }
387388
388389 macro_rules! lsp_test {
389- ( $cwd : expr , [ $( $arguments: expr ) ,* ] , [ $( $messages: expr ) ,* ] , [ $( $tests: expr ) ,* ] ) => {
390+ ( [ $( $arguments: expr ) ,* ] , [ $( $messages: expr ) ,* ] , [ $( $tests: expr ) ,* ] ) => {
390391 let opt = Opt :: parse_from( vec![ "BINARY_NAME" , "--lsp" , $( $arguments) * ] ) ;
391392 let mut config_resolver = ConfigResolver :: new( & opt) . unwrap( ) ;
392393
@@ -416,6 +417,18 @@ mod tests {
416417 } )
417418 }
418419
420+ fn initialize_with_options ( id : i32 , options : InitializationOptions ) -> Message {
421+ Message :: Request ( Request {
422+ id : RequestId :: from ( id) ,
423+ method : <Initialize as lsp_types:: request:: Request >:: METHOD . to_string ( ) ,
424+ params : to_value ( InitializeParams {
425+ initialization_options : Some ( to_value ( options) . unwrap ( ) ) ,
426+ ..Default :: default ( )
427+ } )
428+ . unwrap ( ) ,
429+ } )
430+ }
431+
419432 fn initialized ( ) -> Message {
420433 Message :: Notification ( Notification {
421434 method : Initialized :: METHOD . to_string ( ) ,
@@ -804,7 +817,6 @@ mod tests {
804817 let uri = Uri :: from_str ( cwd. child ( "foo.lua" ) . to_str ( ) . unwrap ( ) ) . unwrap ( ) ;
805818
806819 lsp_test ! (
807- cwd,
808820 [ ] ,
809821 [
810822 initialize( 1 , Some ( cwd. path( ) ) ) ,
@@ -837,7 +849,6 @@ mod tests {
837849 let uri = Uri :: from_str ( cwd. child ( "foo.lua" ) . to_str ( ) . unwrap ( ) ) . unwrap ( ) ;
838850
839851 lsp_test ! (
840- cwd,
841852 [ ] ,
842853 [
843854 initialize( 1 , Some ( cwd. path( ) ) ) ,
@@ -871,7 +882,6 @@ mod tests {
871882 let uri = Uri :: from_str ( cwd. child ( "foo.lua" ) . to_str ( ) . unwrap ( ) ) . unwrap ( ) ;
872883
873884 lsp_test ! (
874- cwd,
875885 [ ] ,
876886 [
877887 initialize( 1 , Some ( cwd. path( ) ) ) ,
@@ -905,7 +915,6 @@ mod tests {
905915 let uri = Uri :: from_str ( cwd. child ( "foo.lua" ) . to_str ( ) . unwrap ( ) ) . unwrap ( ) ;
906916
907917 lsp_test ! (
908- cwd,
909918 [ "--search-parent-directories" ] ,
910919 [
911920 initialize( 1 , Some ( cwd. path( ) ) ) ,
@@ -938,7 +947,6 @@ mod tests {
938947 let uri = Uri :: from_str ( cwd. child ( "build/foo.lua" ) . to_str ( ) . unwrap ( ) ) . unwrap ( ) ;
939948
940949 lsp_test ! (
941- cwd,
942950 [ ] ,
943951 [
944952 initialize( 1 , Some ( cwd. path( ) ) ) ,
@@ -959,4 +967,84 @@ mod tests {
959967 ]
960968 ) ;
961969 }
970+
971+ #[ test]
972+ fn test_lsp_does_not_use_editor_formatting_options ( ) {
973+ let uri = Uri :: from_str ( "file:///home/documents/file.luau" ) . unwrap ( ) ;
974+ let contents = "do print(1) end" ;
975+
976+ lsp_test ! (
977+ [ ] ,
978+ [
979+ initialize_with_options(
980+ 1 ,
981+ InitializationOptions {
982+ respect_editor_formatting_options: None ,
983+ }
984+ ) ,
985+ initialized( ) ,
986+ open_text_document( uri. clone( ) , contents. to_string( ) ) ,
987+ format_document(
988+ 2 ,
989+ uri. clone( ) ,
990+ FormattingOptions {
991+ tab_size: 2 ,
992+ insert_spaces: true ,
993+ ..Default :: default ( )
994+ }
995+ ) ,
996+ shutdown( 3 ) ,
997+ exit( )
998+ ] ,
999+ [
1000+ |receiver| expect_server_initialized( receiver, 1 ) ,
1001+ |receiver| {
1002+ let edits: Vec <TextEdit > = expect_response( receiver, 2 ) ;
1003+ let formatted = apply_text_edits_to( contents, edits) ;
1004+ assert_eq!( formatted, "do\n \t print(1)\n end\n " ) ;
1005+ } ,
1006+ |receiver| expect_server_shutdown( receiver, 3 )
1007+ ]
1008+ ) ;
1009+ }
1010+
1011+ #[ test]
1012+ fn test_lsp_respects_editor_formatting_options_if_enabled ( ) {
1013+ let uri = Uri :: from_str ( "file:///home/documents/file.luau" ) . unwrap ( ) ;
1014+ let contents = "do print(1) end" ;
1015+
1016+ lsp_test ! (
1017+ [ ] ,
1018+ [
1019+ initialize_with_options(
1020+ 1 ,
1021+ InitializationOptions {
1022+ respect_editor_formatting_options: Some ( true )
1023+ }
1024+ ) ,
1025+ initialized( ) ,
1026+ open_text_document( uri. clone( ) , contents. to_string( ) ) ,
1027+ format_document(
1028+ 2 ,
1029+ uri. clone( ) ,
1030+ FormattingOptions {
1031+ tab_size: 2 ,
1032+ insert_spaces: true ,
1033+ ..Default :: default ( )
1034+ }
1035+ ) ,
1036+ shutdown( 3 ) ,
1037+ exit( )
1038+ ] ,
1039+ [
1040+ |receiver| expect_server_initialized( receiver, 1 ) ,
1041+ |receiver| {
1042+ let edits: Vec <TextEdit > = expect_response( receiver, 2 ) ;
1043+ let formatted = apply_text_edits_to( contents, edits) ;
1044+ assert_eq!( formatted, "do\n print(1)\n end\n " ) ;
1045+ } ,
1046+ |receiver| expect_server_shutdown( receiver, 3 )
1047+ ]
1048+ ) ;
1049+ }
9621050}
0 commit comments