diff --git a/src/LanguageServer.php b/src/LanguageServer.php index 9208e8df..f6dfb4a6 100644 --- a/src/LanguageServer.php +++ b/src/LanguageServer.php @@ -6,6 +6,7 @@ use LanguageServer\Protocol\{ServerCapabilities, ClientCapabilities, TextDocumentSyncKind, Message}; use LanguageServer\Protocol\InitializeResult; use AdvancedJsonRpc\{Dispatcher, ResponseError, Response as ResponseBody, Request as RequestBody}; +use LanguageServer\Protocol\CompletionOptions; class LanguageServer extends \AdvancedJsonRpc\Dispatcher { @@ -76,6 +77,10 @@ public function initialize(string $rootPath, int $processId, ClientCapabilities $serverCapabilities->documentSymbolProvider = true; // Support "Format Code" $serverCapabilities->documentFormattingProvider = true; + + $completionOptions = new CompletionOptions(); + $completionOptions->resolveProvider = false; + $serverCapabilities->completionProvider = $completionOptions; return new InitializeResult($serverCapabilities); } diff --git a/src/Protocol/CompletionItem.php b/src/Protocol/CompletionItem.php index 780f31f4..b993ac7a 100644 --- a/src/Protocol/CompletionItem.php +++ b/src/Protocol/CompletionItem.php @@ -60,14 +60,14 @@ class CompletionItem */ public $insertText; - /** - * An edit which is applied to a document when selecting - * this completion. When an edit is provided the value of - * insertText is ignored. - * - * @var TextEdit|null - */ - public $textEdit; +// /** +// * An edit which is applied to a document when selecting +// * this completion. When an edit is provided the value of +// * insertText is ignored. +// * +// * @var TextEdit|null +// */ +// public $textEdit; /** * An data entry field that is preserved on a completion item between diff --git a/src/Protocol/CompletionKind.php b/src/Protocol/CompletionItemKind.php similarity index 100% rename from src/Protocol/CompletionKind.php rename to src/Protocol/CompletionItemKind.php diff --git a/src/Server/Completion/KeywordData.php b/src/Server/Completion/KeywordData.php new file mode 100644 index 00000000..fe24b7e8 --- /dev/null +++ b/src/Server/Completion/KeywordData.php @@ -0,0 +1,30 @@ +label = $label; + if ($insertText == null) { + $this->insertText = $label; + } else { + $this->insertText = $insertText; + } + } + + public function getLabel() + { + return $this->label; + } + + public function getInsertText() + { + return $this->insertText; + } +} \ No newline at end of file diff --git a/src/Server/Completion/PHPKeywords.php b/src/Server/Completion/PHPKeywords.php new file mode 100644 index 00000000..ae2b15c9 --- /dev/null +++ b/src/Server/Completion/PHPKeywords.php @@ -0,0 +1,99 @@ +keywords = [ + new KeywordData("abstract"), + new KeywordData("and"), + new KeywordData("array"), + new KeywordData("as"), + new KeywordData("break"), + new KeywordData("callable"), + new KeywordData("case"), + new KeywordData("catch"), + new KeywordData("class"), + new KeywordData("clone"), + new KeywordData("const"), + new KeywordData("continue"), + new KeywordData("declare"), + new KeywordData("default"), + new KeywordData("die"), + new KeywordData("do"), + new KeywordData("echo"), + new KeywordData("else"), + new KeywordData("elseif"), + new KeywordData("empty"), + new KeywordData("enddeclare"), + new KeywordData("endfor"), + new KeywordData("endforeach"), + new KeywordData("endif"), + new KeywordData("endswitch"), + new KeywordData("endwhile"), + new KeywordData("eval"), + new KeywordData("exit"), + new KeywordData("extends"), + new KeywordData("false"), + new KeywordData("final"), + new KeywordData("finally"), + new KeywordData("for", "for ()"), + new KeywordData("foreach", "foreach ()"), + new KeywordData("function"), + new KeywordData("global"), + new KeywordData("goto"), + new KeywordData("if", "if ()"), + new KeywordData("implements"), + new KeywordData("include"), + new KeywordData("include_once"), + new KeywordData("instanceof"), + new KeywordData("insteadof"), + new KeywordData("interface"), + new KeywordData("isset"), + new KeywordData("list"), + new KeywordData("namespace"), + new KeywordData("new"), + new KeywordData("null"), + new KeywordData("or"), + new KeywordData("parent"), + new KeywordData("print"), + new KeywordData("private"), + new KeywordData("protected"), + new KeywordData("public"), + new KeywordData("require"), + new KeywordData("require_once"), + new KeywordData("return"), + new KeywordData("self"), + new KeywordData("static"), + new KeywordData("switch", "switch ()"), + new KeywordData("throw"), + new KeywordData("trait"), + new KeywordData("true"), + new KeywordData("try"), + new KeywordData("unset"), + new KeywordData("use"), + new KeywordData("var"), + new KeywordData("while"), + new KeywordData("xor"), + new KeywordData("yield") + ]; + } + + /** + * List of supported PHP keywords + * + * @return KeywordData[] + */ + public function getKeywords() + { + return $this->keywords; + } +} \ No newline at end of file diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index 23c01c02..a5367caf 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -15,8 +15,11 @@ Range, Position, FormattingOptions, - TextEdit + TextEdit, + CompletionItem, + CompletionItemKind }; +use LanguageServer\Server\Completion\PHPKeywords; /** * Provides method handlers for all textDocument/* methods @@ -27,7 +30,7 @@ class TextDocument * @var \PhpParser\Parser */ private $parser; - + /** * A map from file URIs to ASTs * @@ -93,7 +96,7 @@ public function didChange(VersionedTextDocumentIdentifier $textDocument, array $ { $this->updateAst($textDocument->uri, $contentChanges[0]->text); } - + /** * Re-parses a source file, updates the AST and reports parsing errors that may occured as diagnostics * @@ -128,6 +131,19 @@ private function updateAst(string $uri, string $content) } } + /** + * The document close notification is sent from the client to the server when the document got closed in the client. + * The document's truth now exists where the document's uri points to (e.g. if the document's + * uri is a file uri the truth now exists on disk). + * + * @param \LanguageServer\Protocol\TextDocumentIdentifier $textDocument + * @return void + */ + public function didClose(TextDocumentIdentifier $textDocument) + { + unset($this->asts[$textDocument->uri]); + } + /** * The document formatting request is sent from the server to the client to format a whole document. * @@ -148,4 +164,19 @@ public function formatting(TextDocumentIdentifier $textDocument, FormattingOptio return [$edit]; } + public function completion(TextDocumentIdentifier $textDocument, Position $position) + { + $items = []; + $keywords = new PHPKeywords(); + foreach ($keywords->getKeywords() as $keyword){ + $item = new CompletionItem(); + $item->label = $keyword->getLabel(); + $item->kind = CompletionItemKind::KEYWORD; + $item->insertText = $keyword->getInsertText(); + $item->detail = "PHP Language Server"; + $items[] = $item; + } + return $items; + } + }