-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support document formatting #8 #10
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace TestNamespace; | ||
|
||
|
||
|
||
|
||
class TestClass | ||
{ | ||
public $testProperty; | ||
|
||
public function testMethod($testParameter) | ||
{ | ||
$testVariable = 123; | ||
|
||
if ( empty($testParameter)){ | ||
echo 'Empty'; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
namespace TestNamespace; | ||
|
||
class TestClass | ||
{ | ||
public $testProperty; | ||
public function testMethod($testParameter) | ||
{ | ||
$testVariable = 123; | ||
if (empty($testParameter)) { | ||
echo 'Empty'; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
namespace LanguageServer\Server; | ||
|
||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer}; | ||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter; | ||
use PhpParser\NodeVisitor\NameResolver; | ||
use LanguageServer\{LanguageClient, ColumnCalculator, SymbolFinder}; | ||
use LanguageServer\Protocol\{ | ||
|
@@ -12,7 +13,9 @@ | |
Diagnostic, | ||
DiagnosticSeverity, | ||
Range, | ||
Position | ||
Position, | ||
FormattingOptions, | ||
TextEdit | ||
}; | ||
|
||
/** | ||
|
@@ -124,4 +127,25 @@ private function updateAst(string $uri, string $content) | |
$this->asts[$uri] = $stmts; | ||
} | ||
} | ||
|
||
/** | ||
* The document formatting request is sent from the server to the client to format a whole document. | ||
* | ||
* @param TextDocumentIdentifier $textDocument The document to format | ||
* @param FormattingOptions $options The format options | ||
* @return TextEdit[] | ||
*/ | ||
public function formatting(TextDocumentIdentifier $textDocument, FormattingOptions $options) | ||
{ | ||
$nodes = $this->asts[$textDocument->uri]; | ||
if (empty($nodes)) { | ||
return []; | ||
} | ||
$prettyPrinter = new PrettyPrinter(); | ||
$edit = new TextEdit(); | ||
$edit->range = new Range(new Position(0, 0), new Position(PHP_INT_MAX, PHP_INT_MAX)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dbaeumer is it okay to do this to update the whole document? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @felixfbecker yes and no. It is always best if an extension provides a minimal edit set since it will preserve the most markers attached to the text. We have code in place that runs a diff in the whole document gets replaced to compute some more minimal diff. However this might be suboptimal as well. So the more fine grain your edits are the better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dbaeumer Of course a minimal text edit is better, but the default implementation of PHPParser's PrettyPrinter will just spit out the new whole new content. We may customize the behavior later, but for now we just wanted to get the feature done. My question was only about wether it is okay to use a very big number (PHP_INT_MAX) to make it update the whole document (even though the EOF offset is much smaller) or if that is not protocol-conform and causes problems. |
||
$edit->newText = $prettyPrinter->prettyPrintFile($nodes); | ||
return [$edit]; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't found anything about it in protocol spec. Most probably it will depend on client implementation. It works for VS Code but if you feel uncomfortable with it I will reorganize code to store opened documents to calculate end position or traverse to last ast node and get end position from it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's okay as-is. Other options would be to use
$nodes[count($nodes) - 1]->getAttribute('fileEndPos')
or introduce a new AST object that holds the statements but also the raw file content.