@@ -40,6 +40,7 @@ import ParseTree;
4040import util ::ParseErrorRecovery ;
4141import util ::Reflective ;
4242import lang ::pico ::\syntax ::Main ;
43+ import lang ::pico ::\syntax ::Format ;
4344import DateTime ;
4445import IO ;
4546import Location ;
@@ -76,87 +77,37 @@ set[LanguageService] picoLanguageServer(bool allowRecovery) = {
7677
7778list [TextEdit ] picoFormattingService (Tree input , loc range , FormattingOptions opts ) {
7879 str original = "<input > " ;
79-
80- // pico tree to box formatting representation
8180 box = toBox (input );
82- box = visit (box ) { case i :I (_) => i [is =opts .tabSize ] };
83-
84- // box to string
81+ box = visit (box ) { case i :I (_) => i [is =opts .tabSize ] }
8582 formatted = format (box );
8683
87- //// line-based modifications
88- // identity operator, to compose with other operators
89- formatLine = str (str s ) { return s ; };
90- if (!opts .insertSpaces ) {
91- // replace indentation spaces with tabs
92- formatLine = indentSpacesAsTabs (opts .tabSize ) o formatLine ;
93- }
9484 if (!opts .trimTrailingWhitespace ) {
9585 // restore trailing whitespace that was lost during tree->box->text, or find a way to not lose it
9686 println ("The Pico formatter does not support maintaining trailing whitespace." );
9787 }
9888
99- // do line-based processing
100- formatted = perLine (formatted , formatLine );
89+ if (!opts .insertSpaces ) {
90+ // replace indentation spaces with tabs
91+ formatted = perLine (formatted , indentSpacesAsTabs (opts .tabSize ));
92+ }
10193
102- // whole-file processing
10394 if (/^.*[^\n ]<newlines :\n *> $/s := original ) {
10495 // replace original final newlines or remove the one introduced by ((format)) (`Box2Text`)
10596 formatted = replaceLast (formatted , "\n " , opts .trimFinalNewlines ? "" : newlines );
10697 }
98+
10799 if (opts .insertFinalNewline ) {
108100 // ensure presence of final newline
109101 formatted = insertFinalNewline (formatted );
110102 }
111103
112- // computelayout differences as edits, and restore comments
113- edits = layoutDiff (input , parse (#start [Program ], formatted ));
104+ // compute layout differences as edits, and restore comments
105+ edits = layoutDiff (input , parse (#start [Program ], formatted , input @ \loc . top ));
114106
115- // TODO Instead of computing all edits and filtering, we can be more efficient by only formatting certain trees.
107+ // instead of computing all edits and filtering, we can be more efficient by only formatting certain trees.
116108 return [e | e <- edits , isContainedIn (e .range , range )];
117109}
118110
119- Box toBox ((Program ) `begin <Declarations decls > <{Statement ";" }* body > end` , FormatOptions opts = formatOptions ())
120- = V ([
121- L ("begin" ),
122- I ([
123- V ([
124- toBox (decls , opts =opts ),
125- toBox (body , opts =opts )
126- ], vs =1 )
127- ]),
128- L ("end" )
129- ]);
130-
131- Box toBox ((Declarations ) `declare <{IdType "," }* decls > ;` , FormatOptions opts = formatOptions ())
132- = V ([
133- L ("declare" ),
134- A ([
135- R ([
136- toBox (id , opts =opts ),
137- L (":" ),
138- H ([toBox (tp , opts =opts ), decl != decls [-1 ] ? L ("," ) : L (";" )], hs =0 )
139- ])
140- | decl :(IdType ) `<Id id > : <Type tp > ` <- decls
141- ])
142- ]);
143-
144- Box toBox (({Statement ";" }*) stmts , FormatOptions opts = formatOptions ())
145- = V ([
146- H ([
147- toBox (stmt , opts =opts ),
148- stmt != stmts [-1 ] ? L (";" ) : NULL ()
149- ], hs =0 )
150- | stmt <- stmts
151- ]);
152-
153- Box toBox ((Statement ) `while <Expression cond > do <{Statement ";" }* body > od` , FormatOptions opts = formatOptions ())
154- = V ([
155- HOV ([L ("while" ), I ([toBox (cond , opts =opts )]), L ("do" )]),
156- I ([toBox (body , opts =opts )]),
157- L ("od" )
158- ]);
159-
160111set [LanguageService ] picoLanguageServer () = picoLanguageServer (false );
161112set [LanguageService ] picoLanguageServerWithRecovery () = picoLanguageServer (true );
162113
0 commit comments