Skip to content

Commit 6169998

Browse files
Michal Niewrzalfelixfbecker
Michal Niewrzal
authored andcommitted
Support document formatting (#10)
1 parent d1b9b33 commit 6169998

File tree

6 files changed

+94
-3
lines changed

6 files changed

+94
-3
lines changed

fixtures/format.php

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace TestNamespace;
4+
5+
6+
7+
8+
class TestClass
9+
{
10+
public $testProperty;
11+
12+
public function testMethod($testParameter)
13+
{
14+
$testVariable = 123;
15+
16+
if ( empty($testParameter)){
17+
echo 'Empty';
18+
}
19+
}
20+
}

fixtures/format_expected.php

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace TestNamespace;
4+
5+
class TestClass
6+
{
7+
public $testProperty;
8+
public function testMethod($testParameter)
9+
{
10+
$testVariable = 123;
11+
if (empty($testParameter)) {
12+
echo 'Empty';
13+
}
14+
}
15+
}

src/LanguageServer.php

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public function initialize(string $rootPath, int $processId, ClientCapabilities
7474
$serverCapabilities->textDocumentSync = TextDocumentSyncKind::FULL;
7575
// Support "Find all symbols"
7676
$serverCapabilities->documentSymbolProvider = true;
77+
// Support "Format Code"
78+
$serverCapabilities->documentFormattingProvider = true;
7779
return new InitializeResult($serverCapabilities);
7880
}
7981

src/Server/TextDocument.php

+25-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace LanguageServer\Server;
44

55
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer};
6+
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
67
use PhpParser\NodeVisitor\NameResolver;
78
use LanguageServer\{LanguageClient, ColumnCalculator, SymbolFinder};
89
use LanguageServer\Protocol\{
@@ -12,7 +13,9 @@
1213
Diagnostic,
1314
DiagnosticSeverity,
1415
Range,
15-
Position
16+
Position,
17+
FormattingOptions,
18+
TextEdit
1619
};
1720

1821
/**
@@ -124,4 +127,25 @@ private function updateAst(string $uri, string $content)
124127
$this->asts[$uri] = $stmts;
125128
}
126129
}
130+
131+
/**
132+
* The document formatting request is sent from the server to the client to format a whole document.
133+
*
134+
* @param TextDocumentIdentifier $textDocument The document to format
135+
* @param FormattingOptions $options The format options
136+
* @return TextEdit[]
137+
*/
138+
public function formatting(TextDocumentIdentifier $textDocument, FormattingOptions $options)
139+
{
140+
$nodes = $this->asts[$textDocument->uri];
141+
if (empty($nodes)) {
142+
return [];
143+
}
144+
$prettyPrinter = new PrettyPrinter();
145+
$edit = new TextEdit();
146+
$edit->range = new Range(new Position(0, 0), new Position(PHP_INT_MAX, PHP_INT_MAX));
147+
$edit->newText = $prettyPrinter->prettyPrintFile($nodes);
148+
return [$edit];
149+
}
150+
127151
}

tests/LanguageServerTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function testInitialize()
4040
'workspaceSymbolProvider' => null,
4141
'codeActionProvider' => null,
4242
'codeLensProvider' => null,
43-
'documentFormattingProvider' => null,
43+
'documentFormattingProvider' => true,
4444
'documentRangeFormattingProvider' => null,
4545
'documentOnTypeFormattingProvider' => null,
4646
'renameProvider' => null

tests/Server/TextDocumentTest.php

+31-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use PHPUnit\Framework\TestCase;
77
use LanguageServer\Tests\MockProtocolStream;
88
use LanguageServer\{Server, Client, LanguageClient};
9-
use LanguageServer\Protocol\{TextDocumentItem, TextDocumentIdentifier, SymbolKind, DiagnosticSeverity};
9+
use LanguageServer\Protocol\{TextDocumentItem, TextDocumentIdentifier, SymbolKind, DiagnosticSeverity, FormattingOptions};
1010
use AdvancedJsonRpc\{Request as RequestBody, Response as ResponseBody};
1111

1212
class TextDocumentTest extends TestCase
@@ -197,4 +197,34 @@ public function publishDiagnostics(string $uri, array $diagnostics)
197197
]]
198198
], json_decode(json_encode($args), true));
199199
}
200+
201+
public function testFormatting()
202+
{
203+
$textDocument = new Server\TextDocument(new LanguageClient(new MockProtocolStream()));
204+
// Trigger parsing of source
205+
$textDocumentItem = new TextDocumentItem();
206+
$textDocumentItem->uri = 'whatever';
207+
$textDocumentItem->languageId = 'php';
208+
$textDocumentItem->version = 1;
209+
$textDocumentItem->text = file_get_contents(__DIR__ . '/../../fixtures/format.php');
210+
$textDocument->didOpen($textDocumentItem);
211+
212+
// how code should look after formatting
213+
$expected = file_get_contents(__DIR__ . '/../../fixtures/format_expected.php');
214+
// Request formatting
215+
$result = $textDocument->formatting(new TextDocumentIdentifier('whatever'), new FormattingOptions());
216+
$this->assertEquals([0 => [
217+
'range' => [
218+
'start' => [
219+
'line' => 0,
220+
'character' => 0
221+
],
222+
'end' => [
223+
'line' => PHP_INT_MAX,
224+
'character' => PHP_INT_MAX
225+
]
226+
],
227+
'newText' => $expected
228+
]], json_decode(json_encode($result), true));
229+
}
200230
}

0 commit comments

Comments
 (0)