1414package org .eclipse .lsp4e .operations .format ;
1515
1616import java .net .URI ;
17+ import java .util .List ;
1718import java .util .Optional ;
1819import java .util .concurrent .CompletableFuture ;
1920
21+ import org .eclipse .jdt .annotation .Nullable ;
2022import org .eclipse .jface .preference .IPreferenceStore ;
2123import org .eclipse .jface .text .BadLocationException ;
2224import org .eclipse .jface .text .IDocument ;
3133import org .eclipse .lsp4j .FormattingOptions ;
3234import org .eclipse .lsp4j .ServerCapabilities ;
3335import org .eclipse .lsp4j .TextDocumentIdentifier ;
36+ import org .eclipse .lsp4j .TextEdit ;
3437import org .eclipse .ui .editors .text .EditorsUI ;
3538import org .eclipse .ui .texteditor .AbstractDecoratedTextEditorPreferenceConstants ;
3639
@@ -49,20 +52,21 @@ public CompletableFuture<Optional<VersionedEdits>> requestFormatting(IDocument d
4952
5053 DocumentFormattingParams params = getFullFormatParams (formatOptions , docId );
5154
52- // TODO: Could refine this algorithm: at present this grabs the first non-null response but the most functional
53- // implementation (if a text selection is present) would try all the servers in turn to see if they supported
54- // range formatting, falling back to a full format if unavailable
55+ // **NOTE:** We let LanguageServers.computeFirst() see the *raw* edit lists so that servers which
56+ // advertise formatting but return no edits (empty list) are treated as "no result" and formatting
57+ // can fall through to the next server (e.g. Vue LS after TS LS on .vue files).
5558 long modificationStamp = DocumentUtil .getDocumentModificationStamp (document );
5659 return executor .computeFirst ((w , ls ) -> w .getServerCapabilitiesAsync ().thenCompose (capabilities -> {
5760 if (isDocumentRangeFormattingSupported (capabilities ) && (textSelection .getLength () > 0 || !isDocumentFormattingSupported (capabilities ))) {
58- return ls .getTextDocumentService (). rangeFormatting ( rangeParams )
59- .thenApply ( edits -> new VersionedEdits ( modificationStamp , edits , document ) );
61+ return ( CompletableFuture < @ Nullable List <? extends TextEdit >>) ls .getTextDocumentService ()
62+ .rangeFormatting ( rangeParams );
6063 } else if (isDocumentFormattingSupported (capabilities )) {
61- return ls .getTextDocumentService (). formatting ( params )
62- .thenApply ( edits -> new VersionedEdits ( modificationStamp , edits , document ) );
64+ return ( CompletableFuture < @ Nullable List <? extends TextEdit >>) ls .getTextDocumentService ()
65+ .formatting ( params );
6366 }
64- return CompletableFuture .<VersionedEdits >completedFuture (null );
65- }));
67+ return CompletableFuture .completedFuture (null );
68+ })).thenApply (
69+ optionalEdits -> optionalEdits .map (edits -> new VersionedEdits (modificationStamp , edits , document )));
6670 }
6771
6872 public static DocumentFormattingParams getFullFormatParams (FormattingOptions formatOptions ,
0 commit comments