diff options
Diffstat (limited to 'elpa/lsp-mode-20220505.630/lsp-php.el')
-rw-r--r-- | elpa/lsp-mode-20220505.630/lsp-php.el | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/elpa/lsp-mode-20220505.630/lsp-php.el b/elpa/lsp-mode-20220505.630/lsp-php.el new file mode 100644 index 0000000..bfb7d2a --- /dev/null +++ b/elpa/lsp-mode-20220505.630/lsp-php.el @@ -0,0 +1,449 @@ +;;; lsp-php.el --- description -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 emacs-lsp maintainers + +;; Author: emacs-lsp maintainers +;; Keywords: lsp, php + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; LSP Clients for the PHP Programming Language. + +;;; Code: + +(require 'lsp-mode) +(require 'lsp-protocol) + +;; PHP Language Server +(defgroup lsp-php nil + "LSP support for PHP, using php-language-server." + :link '(url-link "https://github.com/felixfbecker/php-language-server") + :group 'lsp-mode) + +(defun lsp-php-get-composer-dir () + "Get composer home directory if possible." + (if (executable-find "composer") + (replace-regexp-in-string "\n$" "" (shell-command-to-string "composer config --global home")) + "~/.composer")) + +(defcustom lsp-php-composer-dir nil + "Home directory of composer." + :group 'lsp-php + :type 'string) + +(defcustom lsp-clients-php-server-command nil + "Install directory for php-language-server." + :group 'lsp-php + :type '(repeat string)) + +(defun lsp-php--create-connection () + "Create lsp connection." + (lsp-stdio-connection + (lambda () + (unless lsp-php-composer-dir + (setq lsp-php-composer-dir (lsp-php-get-composer-dir))) + (unless lsp-clients-php-server-command + (setq lsp-clients-php-server-command + `("php", + (expand-file-name + (f-join lsp-php-composer-dir "vendor/felixfbecker/language-server/bin/php-language-server.php"))))) + lsp-clients-php-server-command) + (lambda () + (if (and (cdr lsp-clients-php-server-command) + (eq (string-match-p "php[0-9.]*\\'" (car lsp-clients-php-server-command)) 0)) + ;; Start with the php command and the list has more elems. Test the existence of the PHP script. + (let ((php-file (nth 1 lsp-clients-php-server-command))) + (or (file-exists-p php-file) + (progn + (lsp-log "%s is not present." php-file) + nil))) + t)))) + +(lsp-register-client + (make-lsp-client :new-connection (lsp-php--create-connection) + :activation-fn (lsp-activate-on "php") + :priority -3 + :server-id 'php-ls)) + +;;; Intelephense +(defgroup lsp-intelephense nil + "LSP support for PHP, using Intelephense." + :group 'lsp-mode + :link '(url-link "https://github.com/bmewburn/vscode-intelephense") + :package-version '(lsp-mode . "6.1")) + +(defcustom-lsp lsp-intelephense-php-version "8.0.1" + "Minimum version of PHP to refer to. Affects code actions, diagnostic & +completions." + :type 'string + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense.environment.phpVersion") + +(defcustom-lsp lsp-intelephense-files-max-size 1000000 + "Maximum file size in bytes." + :type 'number + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense-files.maxSize") + +(defcustom-lsp lsp-intelephense-files-associations + ["*.php" "*.phtml"] + "Configure glob patterns to make files available for language +server features." + :type '(repeat string) + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense.files.associations") + +(defcustom-lsp lsp-intelephense-files-exclude + ["**/.git/**" "**/.svn/**" "**/.hg/**" "**/CVS/**" "**/.DS_Store/**" + "**/node_modules/**" "**/bower_components/**" "**/vendor/**/{Test,test,Tests,tests}/**"] + "Configure glob patterns to exclude certain files and folders +from all language server features." + :type '(repeat string) + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense.files.exclude") + +(defcustom-lsp lsp-intelephense-stubs + ["apache" "bcmath" "bz2" "calendar" + "com_dotnet" "Core" "ctype" "curl" "date" "dba" "dom" "enchant" + "exif" "fileinfo" "filter" "fpm" "ftp" "gd" "hash" "iconv" "imap" "interbase" + "intl" "json" "ldap" "libxml" "mbstring" "mcrypt" "meta" "mssql" "mysqli" + "oci8" "odbc" "openssl" "pcntl" "pcre" "PDO" "pdo_ibm" "pdo_mysql" + "pdo_pgsql" "pdo_sqlite" "pgsql" "Phar" "posix" "pspell" "readline" "recode" + "Reflection" "regex" "session" "shmop" "SimpleXML" "snmp" "soap" "sockets" + "sodium" "SPL" "sqlite3" "standard" "superglobals" "sybase" "sysvmsg" + "sysvsem" "sysvshm" "tidy" "tokenizer" "wddx" "xml" "xmlreader" "xmlrpc" + "xmlwriter" "Zend OPcache" "zip" "zlib"] + "Configure stub files for built in symbols and common +extensions. The default setting includes PHP core and all +bundled extensions." + :type '(repeat string) + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense.stubs") + +(defcustom-lsp lsp-intelephense-completion-insert-use-declaration t + "Use declarations will be automatically inserted for namespaced +classes, traits, interfaces, functions, and constants." + :type 'boolean + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense.completion.insertUseDeclaration") + +(defcustom-lsp lsp-intelephense-completion-fully-qualify-global-constants-and-functions nil + "Global namespace constants and functions will be fully +qualified (prefixed with a backslash)." + :type 'boolean + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense.completion.fullyQualifyGlobalConstantsAndFunctions") + +(defcustom-lsp lsp-intelephense-completion-trigger-parameter-hints t + "Method and function completions will include parentheses and +trigger parameter hints." + :type 'boolean + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.2") + :lsp-path "intelephense.completion.triggerParameterHints") + +(defcustom-lsp lsp-intelephense-completion-max-items 100 + "The maximum number of completion items returned per request." + :type 'number + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.2") + :lsp-path "intelephense.completion.maxItems") + +(defcustom-lsp lsp-intelephense-format-enable t + "Enables formatting." + :type 'boolean + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense.format.enable") + +(defcustom lsp-intelephense-licence-key nil + "Enter your intelephense licence key here to access premium +features." + :type 'string + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.2")) + +(defcustom-lsp lsp-intelephense-telemetry-enabled nil + "Anonymous usage and crash data will be sent to Azure +Application Insights." + :type 'boolean + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.2") + :lsp-path "intelephense.telemetry.enabled") + +(defcustom-lsp lsp-intelephense-rename-exclude + ["**/vendor/**"] + "Glob patterns to exclude files and folders from having symbols +renamed. Rename operation will fail if references and/or +definitions are found in excluded files/folders." + :type '(repeat string) + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.2") + :lsp-path "intelephense.rename.exclude") + +(defcustom-lsp lsp-intelephense-trace-server "off" + "Traces the communication between VSCode and the intelephense +language server." + :type '(choice (:tag "off" "messages" "verbose")) + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1") + :lsp-path "intelephense.trace.server") + +(defcustom lsp-intelephense-storage-path + (expand-file-name (locate-user-emacs-file "lsp-cache")) + "Optional absolute path to storage dir." + :type 'directory + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1")) + +(defcustom lsp-intelephense-global-storage-path + (expand-file-name (locate-user-emacs-file "intelephense")) + "Optional absolute path to global storage dir." + :type 'directory + :group 'lsp-intelephense + :package-version '(lsp-mode . "8.0.1")) + +(defcustom lsp-intelephense-clear-cache nil + "Optional flag to clear server state." + :type 'boolean + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.2")) + +(defcustom lsp-intelephense-multi-root t + "Flag to control if the server supports multi-root projects." + :type 'boolean + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.3")) + +(define-obsolete-variable-alias + 'lsp-clients-php-iph-server-command + 'lsp-intelephense-server-command + "lsp-mode 6.1") + +(defcustom lsp-intelephense-server-command + `("intelephense" "--stdio") + "Command to start Intelephense." + :type '(repeat string) + :group 'lsp-intelephense + :package-version '(lsp-mode . "6.1")) + +(lsp-dependency 'intelephense + '(:system "intelephense") + '(:npm :package "intelephense" + :path "intelephense")) + +(lsp-register-client + (make-lsp-client :new-connection (lsp-stdio-connection + (lambda () + `(,(or (executable-find + (cl-first lsp-intelephense-server-command)) + (lsp-package-path 'intelephense)) + ,@(cl-rest lsp-intelephense-server-command)))) + :activation-fn (lsp-activate-on "php") + :priority -1 + :notification-handlers (ht ("indexingStarted" #'ignore) + ("indexingEnded" #'ignore)) + :initialization-options (lambda () + (list :storagePath lsp-intelephense-storage-path + :globalStoragePath lsp-intelephense-global-storage-path + :licenceKey lsp-intelephense-licence-key + :clearCache lsp-intelephense-clear-cache)) + :multi-root lsp-intelephense-multi-root + :completion-in-comments? t + :server-id 'iph + :download-server-fn (lambda (_client callback error-callback _update?) + (lsp-package-ensure 'intelephense + callback error-callback)) + :synchronize-sections '("intelephense"))) + + +;;; Serenata +(defgroup lsp-serenata nil + "LSP support for the PHP programming language, using serenata." + :group 'lsp-mode + :link '(url-link "https://gitlab.com/Serenata/Serenata") + :package-version '(lsp-mode . "7.0")) + +(defcustom lsp-serenata-server-path + "serenata.phar" + "Path to the Serenata Language Server phar file. +It can be downloaded from https://gitlab.com/Serenata/Serenata/-/releases." + :group 'lsp-serenata + :type 'file) + +(defcustom lsp-serenata-uris + [] + "A list of folders to index for your project. +This does not have to include the root of the project itself, in +case you have need of an exotic configuration where the root of +the project is at some location but your actual PHP code is +somewhere else. Note that if you are running Serenata in a +container, you will have to ensure that these URI's are mapped +inside it. Avoid using file paths containing spaces. This is +currently broken due to apparent PHP quirks. By default, the +value is taken from the lsp workspace location." + :group 'lsp-serenata + :type 'lsp-string-vector) + +(defcustom lsp-serenata-php-version + 7.3 + "Allows you to specify the PHP version your project is written in. +At the moment this directive is still ignored, but it will +influence functionality such as refactoring in the future, where +older PHP versions may not support scalar type hints, which may +then be omitted from places such as getters and setters." + :group 'lsp-serenata + :type 'number) + +(defcustom lsp-serenata-file-extensions + ["php"] + "List of file extensions (without dot) to process. +Files that do not match this whitelist will be ignored during +indexing. Usually you'll want to set this to at least include +php, as it is the most common PHP extension. phpt is not +included by default as it is often used to contain test code that +is not directly part of the code. Note that for existing +projects, removing extensions will not not automatically prune +files having them from the index if they are already present. +Adding new ones will cause the files having them to be picked up +on the next project initialization." + :group 'lsp-serenata + :type 'lsp-string-vector) + +(defcustom lsp-serenata-index-database-uri (lsp--path-to-uri (f-join user-emacs-directory "index.sqlite")) + "The location to store the index database. +Note that, as the index database uses SQLite and WAL mode, +additional files (usually two) may be generated and used in the +same folder. Note also that Serenata relies on the Doctrine DBAL +library as well as the SQLite backends in PHP, which may not +support non-file URI's, which may prevent you from using these." + :group 'lsp-serenata + :type 'file) + +(defcustom lsp-serenata-exclude-path-expressions ["/.+Test.php$/"] + "One or more expressions of paths to ignore. +This uses Symfony's Finder in the background, so this means you +can configure anything here that can also be passed to the name +function, which includes plain strings, globs, as well as regular +expressions. Note that for existing projects, modifying these +will not not automatically prune them from the index if they are +already present." + :group 'lsp-serenata + :type 'lsp-string-vector) + +(defun lsp-serenata-server-start-fun (port) + "Define serenata start function, it requires a PORT." + `(,lsp-serenata-server-path + "-u" ,(number-to-string port))) + +(defun lsp-serenata-init-options () + "Init options for lsp-serenata." + `( :configuration ( :uris ,lsp-serenata-uris + :indexDatabaseUri ,lsp-serenata-index-database-uri + :phpVersion ,lsp-serenata-php-version + :excludedPathExpressions ,lsp-serenata-exclude-path-expressions + :fileExtensions ,lsp-serenata-file-extensions))) + + +(lsp-interface (serenata:didProgressIndexing (:sequenceOfIndexedItem :totalItemsToIndex :progressPercentage :folderUri :fileUri :info) nil )) + +(lsp-register-client + (make-lsp-client + :new-connection (lsp-tcp-connection 'lsp-serenata-server-start-fun) + :activation-fn (lsp-activate-on "php") + :priority -2 + :notification-handlers (ht ("serenata/didProgressIndexing" + (lambda (_server data) + (lsp-log "%s" (lsp:serenata-did-progress-indexing-info data))))) + + :initialization-options #'lsp-serenata-init-options + :initialized-fn (lambda (workspace) + (when (equal (length lsp-serenata-uris) 0) + (let* ((lsp-root (lsp--path-to-uri (lsp-workspace-root)))) + (setq lsp-serenata-uris (vector lsp-root)))) + (with-lsp-workspace workspace + (lsp--set-configuration + (lsp-configuration-section "serenata")))) + :server-id 'serenata)) + +;;; phpactor + +(defgroup lsp-phpactor nil + "LSP support for Phpactor." + :link '(url-link "https://github.com/phpactor/phpactor") + :group 'lsp-mode) + +(defcustom lsp-phpactor-path nil + "Path to the `phpactor' command." + :group 'lsp-phpactor + :type "string") + +(lsp-register-client + (make-lsp-client + :new-connection (lsp-stdio-connection + (lambda () + (unless lsp-php-composer-dir + (setq lsp-php-composer-dir (lsp-php-get-composer-dir))) + (unless lsp-phpactor-path + (setq lsp-phpactor-path (or (executable-find "phpactor") + (f-join lsp-php-composer-dir "vendor/phpactor/phpactor/bin/phpactor")))) + (list lsp-phpactor-path "language-server"))) + :activation-fn (lsp-activate-on "php") + ;; `phpactor' is not really that feature-complete: it doesn't support + ;; `textDocument/showOccurence' and sometimes errors (e.g. find references on + ;; a global free-standing function). + :priority -4 + ;; Even though `phpactor' itself supports no options, this needs to be + ;; serialized as an empty object (otherwise the LS won't even start, due to a + ;; type error). + :initialization-options (ht) + :server-id 'phpactor)) + +(defcustom lsp-phpactor-extension-alist '(("Phpstan" . "phpactor/language-server-phpstan-extension") + ("Behat" . "phpactor/behat-extension") + ("PHPUnit" . "phpactor/phpunit-extension")) + "Alist mapping extension names to `composer' packages. +These extensions can be installed using +`lsp-phpactor-install-extension'." + :type '(alist :key-type "string" :value-type "string") + :group 'lsp-phpactor) + +(defun lsp-phpactor-install-extension (extension) + "Install a `phpactor' EXTENSION. +See `lsp-phpactor-extension-alist' and +https://phpactor.readthedocs.io/en/develop/extensions.html." + (interactive (list (completing-read "Select extension: " + lsp-phpactor-extension-alist))) + (compilation-start + (format "%s extension:install %s" + (shell-quote-argument (expand-file-name lsp-phpactor-path)) + (shell-quote-argument + (cdr (assoc extension lsp-phpactor-extension-alist)))) + nil + (lambda (_mode) + (format "*Phpactor install %s*" extension)))) + +(lsp-consistency-check lsp-php) + +(provide 'lsp-php) +;;; lsp-php.el ends here |