diff --git a/src/FilesFinder/ClientFilesFinder.php b/src/FilesFinder/ClientFilesFinder.php new file mode 100644 index 0000000..b8ace99 --- /dev/null +++ b/src/FilesFinder/ClientFilesFinder.php @@ -0,0 +1,47 @@ +client = $client; + } + + /** + * Returns all files in the workspace that match a glob. + * If the client does not support workspace/files, it falls back to searching the file system directly. + * + * @param string $glob + * @return Promise The URIs + */ + private function find(string $glob): Promise + { + return $this->client->workspace->xfiles()->then(function (array $textDocuments) { + $uris = []; + foreach ($textDocuments as $textDocument) { + $path = Uri\parse($textDocument->uri)['path']; + if (Glob::match($path, $pattern)) { + $uris[] = $textDocument->uri; + } + } + return $uris; + }); + } +} diff --git a/src/FilesFinder/FileSystemFilesFinder.php b/src/FilesFinder/FileSystemFilesFinder.php new file mode 100644 index 0000000..5cf3541 --- /dev/null +++ b/src/FilesFinder/FileSystemFilesFinder.php @@ -0,0 +1,30 @@ + + */ + public function find(string $glob): Promise + { + return coroutine(function () use ($glob) { + $uris = []; + foreach (new GlobIterator($pattern) as $path) { + $uris[] = pathToUri($path); + yield timeout(); + } + return $uris; + }); + } +} diff --git a/src/FilesFinder/FilesFinder.php b/src/FilesFinder/FilesFinder.php new file mode 100644 index 0000000..9822856 --- /dev/null +++ b/src/FilesFinder/FilesFinder.php @@ -0,0 +1,21 @@ + + */ + public function find(string $glob): Promise; +} diff --git a/src/LanguageServer.php b/src/LanguageServer.php index 42a1b64..d579bf5 100644 --- a/src/LanguageServer.php +++ b/src/LanguageServer.php @@ -14,13 +14,12 @@ use LanguageServer\Protocol\{ TextDocumentIdentifier, CompletionOptions }; +use LanguageServer\FilesFinder\{FilesFinder, ClientFilesFinder, FileSystemFilesFinder}; use AdvancedJsonRpc; use Sabre\Event\{Loop, Promise}; use function Sabre\Event\coroutine; use Exception; use Throwable; -use Webmozart\Glob\Iterator\GlobIterator; -use Webmozart\Glob\Glob; use Webmozart\PathUtil\Path; use Sabre\Uri; @@ -62,6 +61,11 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher private $rootPath; private $project; + /** + * @var FilesFinder + */ + private $filesFinder; + public function __construct(ProtocolReader $reader, ProtocolWriter $writer) { parent::__construct($this, '/'); @@ -107,6 +111,11 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher }); $this->protocolWriter = $writer; $this->client = new LanguageClient($reader, $writer); + if ($this->clientCapabilities->xfilesProvider) { + $this->filesFinder = new ClientFilesFinder($this->client); + } else { + $this->filesFinder = new FileSystemFilesFinder; + } } /** @@ -183,7 +192,8 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher private function indexProject(): Promise { return coroutine(function () { - $textDocuments = yield $this->findPhpFiles(); + $pattern = Path::makeAbsolute('**/*.php', $this->rootPath); + $textDocuments = yield $this->filesFinder->find($pattern); $count = count($textDocuments); $startTime = microtime(true); @@ -219,33 +229,4 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher }); } - /** - * Returns all PHP files in the workspace. - * If the client does not support workspace/files, it falls back to searching the file system directly. - * - * @return Promise - */ - private function findPhpFiles(): Promise - { - return coroutine(function () { - $textDocuments = []; - $pattern = Path::makeAbsolute('**/*.php', $this->rootPath); - if ($this->clientCapabilities->xfilesProvider) { - // Use xfiles request - foreach (yield $this->client->workspace->xfiles() as $textDocument) { - $path = Uri\parse($textDocument->uri)['path']; - if (Glob::match($path, $pattern)) { - $textDocuments[] = $textDocument; - } - } - } else { - // Use the file system - foreach (new GlobIterator($pattern) as $path) { - $textDocuments[] = new TextDocumentIdentifier(pathToUri($path)); - yield timeout(); - } - } - return $textDocuments; - }); - } }