From 67d818928af5b5748021f26ebc0ea1d02420e932 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Tue, 11 Oct 2022 01:15:28 +0900 Subject: [PATCH 1/9] Add php-ide-phpactor.el --- Cask | 2 + Makefile | 1 + lisp/php-ide-phpactor.el | 127 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 lisp/php-ide-phpactor.el diff --git a/Cask b/Cask index 1d85fe49..b0e67ed7 100644 --- a/Cask +++ b/Cask @@ -11,9 +11,11 @@ "lisp/php-format.el" "lisp/php-project.el" "lisp/php-local-manual.el" + "lisp/php-ide-phpactor.el" "lisp/php-mode-debug.el") (development + (depends-on "phpactor") (depends-on "pkg-info") (depends-on "projectile") (depends-on "smart-jump") diff --git a/Makefile b/Makefile index 12aadcda..dc60f900 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ ELS += lisp/php-defs.el ELS += lisp/php-face.el ELS += lisp/php-flymake.el ELS += lisp/php-format.el +ELS += lisp/php-ide-phpactor.el ELS += lisp/php-local-manual.el ELS += lisp/php-mode-debug.el ELS += lisp/php-mode.el diff --git a/lisp/php-ide-phpactor.el b/lisp/php-ide-phpactor.el new file mode 100644 index 00000000..3f73c80e --- /dev/null +++ b/lisp/php-ide-phpactor.el @@ -0,0 +1,127 @@ +;;; php-ide-phpactor.el --- PHP-IDE feature using Phpactor RPC -*- lexical-binding: t; -*- + +;; Copyright (C) 2023 Friends of Emacs-PHP development + +;; Author: USAMI Kenta +;; Keywords: tools, files +;; URL: https://github.com/emacs-php/php-mode +;; Version: 1.24.0 +;; License: GPL-3.0-or-later + +;; 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 . + +;;; Commentary: + +;; PHP-IDE implementation to integrate Phpactor (phpactor.el). +;; This feature depends on . + +;;; Code: +(require 'phpactor nil t) +(require 'popup nil t) +(require 'smart-jump nil t) +(eval-when-compile + (require 'cl-lib)) + +(defvar-local php-ide-phpactor-buffer nil) +(defvar-local php-ide-phpactor-hover-last-pos nil) +(defvar-local php-ide-phpactor-hover-last-msg nil) + +(declare-function phpactor--command-argments "ext:phpactor" (&rest arg-keys)) +(declare-function phpactor--parse-json "ext:phpactor" (buffer)) +(declare-function phpactor--rpc-async "ext:phpactor" (action arguments callback)) +(declare-function phpactor-goto-definition "ext:phpactor" ()) +(declare-function popup-tip "ext:popup" (string)) +(declare-function smart-jump-back "ext:smart-jump" ()) +(declare-function smart-jump-go "ext:smart-jump" (&optional smart-list continue)) +(declare-function smart-jump-references "ext:smart-jump" (&optional smart-list continue)) + +(defgroup php-ide-phpactor nil + "UI support for PHP developing." + :tag "PHP-IDE Phpactor" + :prefix "php-ide-phpactor-" + :group 'php-ide) + +(defcustom php-ide-phpactor-activate-features '(all) + "A set of Phpactor features you want to enable." + :tag "PHP-IDE Phpactor Activate Features" + :type '(set (const all :tag "All") + (const hover) + (const navigation)) + :safe (lambda (v) (and (listp v))) + :group 'php-ide-phpactor) + +(defvar php-ide-phpactor-timer nil + "Timer object for execute Phpactor and display hover message.") + +(defvar php-ide-phpactor-disable-hover-at-point-functions + '(php-in-string-or-comment-p)) + +(defun php-ide-phpactor--disable-hover-at-point-p () + "Return non-NIL if any function return non-NIL for disable to hover at point." + (cl-loop for f in php-ide-phpactor-disable-hover-at-point-functions + never (not (funcall f)))) + +(defun php-ide-phpactor-hover () + "Show brief information about the symbol underneath the cursor." + (interactive) + (when (and php-ide-phpactor-buffer (not (php-ide-phpactor--disable-hover-at-point-p))) + (if (eq (point) php-ide-phpactor-hover-last-pos) + (when php-ide-phpactor-hover-last-msg + (let ((msg php-ide-phpactor-hover-last-msg)) + (setq php-ide-phpactor-hover-last-msg nil) + (popup-tip msg))) + (setq php-ide-phpactor-hover-last-pos (point)) + (let ((main-buffer (current-buffer))) + (phpactor--rpc-async "hover" (phpactor--command-argments :source :offset) + (lambda (proc) + (let* ((response (phpactor--parse-json (process-buffer proc))) + (msg (plist-get (plist-get response :parameters) :message))) + (with-current-buffer main-buffer + (setq php-ide-phpactor-hover-last-msg msg))))))))) + +(defsubst php-ide-phpactor--feature-activated-p (feature) + "Is FEATURE activated in `php-ide-phpactor-activate-features'." + (or (memq 'all php-ide-phpactor-activate-features) + (memq feature php-ide-phpactor-activate-features))) + +;;;###autoload +(defun php-ide-phpactor-activate () + "Activate PHP-IDE using phpactor.el." + (interactive) + (when (php-ide-phpactor--feature-activated-p 'navigation) + (if (not (bound-and-true-p phpactor-smart-jump-initialized)) + (local-set-key [remap xref-find-definitions] #'phpactor-goto-definition) + (local-set-key [remap xref-find-definitions] #'smart-jump-go) + (local-set-key [remap xref-pop-marker-stack] #'smart-jump-back) + (local-set-key [remap xref-find-references] #'smart-jump-references))) + (when (php-ide-phpactor--feature-activated-p 'hover) + (unless php-ide-phpactor-timer + (setq php-ide-phpactor-timer (run-with-timer 0.8 0.8 #'php-ide-phpactor-hover)))) + (setq php-ide-phpactor-buffer t)) + +;;;###autoload +(defun php-ide-phpactor-deactivate () + "Dectivate PHP-IDE using phpactor.el." + (interactive) + (local-unset-key [remap xref-find-definitions]) + (local-unset-key [remap xref-pop-marker-stack]) + (local-unset-key [remap xref-find-references]) + + (when php-ide-phpactor-timer + (cancel-timer php-ide-phpactor-timer) + (setq php-ide-phpactor-timer nil)) + (setq php-ide-phpactor-buffer nil)) + +(provide 'php-ide-phpactor) +;;; php-ide-phpactor.el ends here From acde9abad2777b9893a062ebc178313b0fb4b2cb Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Tue, 11 Oct 2022 01:58:36 +0900 Subject: [PATCH 2/9] Add php-eglot.el --- Cask | 1 + Makefile | 1 + lisp/php-eglot.el | 116 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 lisp/php-eglot.el diff --git a/Cask b/Cask index b0e67ed7..e090d524 100644 --- a/Cask +++ b/Cask @@ -7,6 +7,7 @@ "lisp/php.el" "lisp/php-complete.el" "lisp/php-defs.el" + "lisp/php-eglot.el" "lisp/php-face.el" "lisp/php-format.el" "lisp/php-project.el" diff --git a/Makefile b/Makefile index dc60f900..c2fc9ffe 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ ELS = lisp/php.el ELS += lisp/php-align.el ELS += lisp/php-complete.el ELS += lisp/php-defs.el +ELS += lisp/php-eglot.el ELS += lisp/php-face.el ELS += lisp/php-flymake.el ELS += lisp/php-format.el diff --git a/lisp/php-eglot.el b/lisp/php-eglot.el new file mode 100644 index 00000000..6a7875f3 --- /dev/null +++ b/lisp/php-eglot.el @@ -0,0 +1,116 @@ +;;; php-eglot.el --- Eglot enhancement for PHP development -*- lexical-binding: t; -*- + +;; Copyright (C) 2023 Friends of Emacs-PHP development + +;; Author: USAMI Kenta +;; Keywords: tools, files +;; URL: https://github.com/emacs-php/php-mode +;; Version: 1.24.0 +;; License: GPL-3.0-or-later + +;; 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 . + +;;; Commentary: + +;; PHP Mode integrates Eglot . +;; +;; **Note**: +;; This feature is under development and experimental. +;; All of these functions, modes and terms are subject to change without notice. +;; +;; ## Configuration +;; +;; Put follows code into your .emacs (~/.emacs.d/init.el) file: +;; +;; (add-to-list 'eglot-server-programs ((php-mode phps-mode) . php-eglot-server-program)) +;; +;; ### For per project configuration +;; +;; Put follows code into .dir-locals.el in project directory: +;; +;; ((nil (php-project-root . git) +;; (php-eglot-executable . ("psalm-language-server")) +;; ;; or (php-eglot-executable . ("php" "vendor/bin/path/to/server")) +;; )) +;; +;; If you can't put .dir-locals.el in your project directory, consider the sidecar-locals package. +;; https://melpa.org/#/sidecar-locals +;; https://codeberg.org/ideasman42/emacs-sidecar-locals +;; + +;;; Code: +(require 'cl-lib) +(require 'php-project) +(require 'eglot nil t) +(require 'phpactor nil t) + +(eval-when-compile + (defvar eglot-server-programs) + (defvar eglot--managed-mode) + (declare-function eglot-ensure "ext:eglot" ()) + (declare-function phpactor--find-executable "ext:phpactor" ())) + +(defvar php-eglot-lsp-command-alist + '((intelephense "intelephense" "--stdio") + (phpactor . (lambda () (list (if (require 'phpactor nil t) + (phpactor--find-executable) + "phpactor")))))) + +(defgroup php-eglot nil + "Eglot PHP integration." + :tag "PHP-Eglot" + :prefix "php-eglot-" + :group 'eglot + :group 'php) + +;;;###autoload +(defcustom php-eglot-executable nil + "Command name or path to the command of Eglot LSP executable." + :tag "Php-Eglot Executable" + :group 'php-eglot + :type '(choice + (const intelephense) + (const phpactor) + string (repeat string)) + :safe (lambda (v) (cond + ((stringp v) (file-exists-p v)) + ((listp v) (cl-every #'stringp v)) + ((assq v php-eglot-lsp-command-alist))))) + +;;;###autoload +(defun php-eglot-server-program () + "Return a list of command to execute LSP Server." + (cond + ((stringp php-eglot-executable) (list php-eglot-executable)) + ((listp php-eglot-executable) php-eglot-executable) + ((when-let (command (assq php-eglot-executable php-eglot-lsp-command-alist)) + (cond + ((functionp command) (funcall command)) + ((listp command) command)))))) + +(defun php-eglot-ensure () + "Start PHP-specific Eglot session for current buffer if there isn't one." + (when-let (server-program (php-eglot-server-program)) + (setq-local eglot-server-programs (list (cons major-mode server-program)))) + (setq-local project-find-functions (list #'php-project-project-find-function)) + (add-function :after (local 'eglot--managed-mode) #'php-eglot--eglot--managed-mode-after) + (eglot-ensure)) + +(defun php-eglot--eglot--managed-mode-after (&optional _arg) + "Rollback variables when turning off `eglot--managed-mode'." + (unless eglot--managed-mode + (setq-local eglot-server-programs (default-value 'eglot-server-programs)))) + +(provide 'php-eglot) +;;; php-eglot.el ends here From bb5bec31ee927e184c1ddc162d0ddbb92d56d633 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Tue, 11 Oct 2022 02:04:47 +0900 Subject: [PATCH 3/9] Add php-ide.el --- Cask | 2 + Makefile | 1 + lisp/php-ide.el | 184 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 lisp/php-ide.el diff --git a/Cask b/Cask index e090d524..0e8d0585 100644 --- a/Cask +++ b/Cask @@ -13,9 +13,11 @@ "lisp/php-project.el" "lisp/php-local-manual.el" "lisp/php-ide-phpactor.el" + "lisp/php-ide.el" "lisp/php-mode-debug.el") (development + ;;(depends-on "lsp-mode") (depends-on "phpactor") (depends-on "pkg-info") (depends-on "projectile") diff --git a/Makefile b/Makefile index c2fc9ffe..42db81da 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ ELS += lisp/php-face.el ELS += lisp/php-flymake.el ELS += lisp/php-format.el ELS += lisp/php-ide-phpactor.el +ELS += lisp/php-ide.el ELS += lisp/php-local-manual.el ELS += lisp/php-mode-debug.el ELS += lisp/php-mode.el diff --git a/lisp/php-ide.el b/lisp/php-ide.el new file mode 100644 index 00000000..e19de0b2 --- /dev/null +++ b/lisp/php-ide.el @@ -0,0 +1,184 @@ +;;; php-ide.el --- IDE-like UI support for PHP development -*- lexical-binding: t; -*- + +;; Copyright (C) 2023 Friends of Emacs-PHP development + +;; Author: USAMI Kenta +;; Keywords: tools, files +;; URL: https://github.com/emacs-php/php-mode +;; Version: 1.24.0 +;; License: GPL-3.0-or-later + +;; 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 . + +;;; Commentary: + +;; PHP Mode integrates LSP Mode (lsp-mode), Phpactor (phpactor.el) and IDE-like tools. +;; +;; **Note**: +;; This feature is under development and experimental. +;; All of these functions, modes and terms are subject to change without notice. +;; +;; ## Motivations +;; +;; There are some IDE-like features / packages for PHP development. +;; PHP-IDE bridges projects and their IDE-like features. +;; +;; ## IDE Features +;; +;; We don't recommend features, but bundle some feature bridges. +;; They are sorted alphabetically except "none." +;; +;; - none +;; Does not launch any IDE features. +;; - eglot +;; https://github.com/joaotavora/eglot +;; - lsp-mode +;; https://emacs-lsp.github.io/lsp-mode/ +;; https://github.com/emacs-lsp/lsp-mode +;; - phpactor +;; https://phpactor.readthedocs.io/ +;; https://github.com/phpactor/phpactor +;; https://github.com/emacs-php/phpactor.el +;; +;; ## Configuration +;; +;; Put follows code into your .emacs (~/.emacs.d/init.el) file: +;; +;; (defun my-php-mode-setup () +;; (add-hook 'hack-local-variables-hook #'php-ide-mode t t)) +;; +;; (with-eval-after-load 'php-ide +;; (custom-set-variables +;; '(php-ide-features . 'eglot) ;; and/or 'none, 'phpactor, 'lsp-mode +;; '(php-ide-eglot-executable "psalm-language-server") ;; or "intelephense", '("php" "vendor/bin/path/to/server") +;; ;; If you want to hide php-ide-mode from the mode line, set an empty string +;; '(php-ide-mode-lighter "")) +;; +;; (add-hook 'php-mode #'my-php-mode-setup)) +;; +;; If you don't enable IDE support by default, set '(php-ide-feature 'none) +;; +;; ### For per project configuration +;; +;; Put follows code into .dir-locals.el in project directory: +;; +;; ((nil (php-project-root . git) +;; (php-ide-features . (lsp-mode)))) +;; +;; If you can't put .dir-locals.el in your project directory, consider the sidecar-locals package. +;; https://melpa.org/#/sidecar-locals +;; https://codeberg.org/ideasman42/emacs-sidecar-locals +;; + +;;; Code: +(require 'php-project) + +(eval-when-compile + (require 'cl-lib) + (require 'php-ide-phpactor) + (defvar eglot-server-programs) + (declare-function eglot-ensure "ext:eglot" ()) + (declare-function eglot--managed-mode-off "ext:eglot" ()) + (declare-function phpactor--find-executable "ext:phpactor" ())) + +(defvar php-ide-feature-alist + '((none :test (lambda () t) + :activate (lambda () t) + :deactivate (lambda () t)) + (phpactor :test (lambda () (and (require 'phpactor nil t) (featurep 'phpactor))) + :activate php-ide-phpactor-activate + :deactivate php-ide-phpactor-activate) + (eglot :test (lambda () (and (require 'eglot nil t) (featurep 'eglot))) + :activate eglot-ensure + :deactivate eglot--managed-mode-off) + (lsp-mode :test (lambda () (and (require 'lsp nil t) (featurep 'lsp))) + :activate lsp + :deactivate lsp-workspace-shutdown))) + +(defvar php-ide-lsp-command-alist + '((intelephense "intelephense" "--stdio") + (phpactor . (lambda () (list (if (fboundp 'phpactor--find-executable) + (phpactor--find-executable) + "phpactor") + "language-server"))))) + +(defgroup php-ide nil + "IDE-like support for PHP developing." + :tag "PHP-IDE" + :prefix "php-ide-" + :group 'php) + +;;;###autoload +(defcustom php-ide-features nil + "A set of PHP-IDE features symbol." + :tag "PHP-IDE Feature" + :group 'php-ide + :type `(set ,@(mapcar (lambda (feature) (list 'const (car feature))) + php-ide-feature-alist) + symbol) + :safe (lambda (v) (cl-loop for feature in (if (listp v) v (list v)) + always (symbolp feature)))) + +(defcustom php-ide-mode-lighter " PHP-IDE" + "A symbol of PHP-IDE feature." + :tag "PHP-IDE Mode Lighter" + :group 'php-ide + :type 'string + :safe #'stringp) + +;;;###autoload +(define-minor-mode php-ide-mode + "Minor mode for integrate IDE-like tools." + :lighter php-ide-mode-lighter + (let ((ide-features php-ide-features)) + (when-let (unavailable-features (cl-loop for feature in ide-features + unless (assq feature php-ide-feature-alist) + collect feature)) + (user-error "%s includes unavailable PHP-IDE features. (available features are: %s)" + ide-features + (mapconcat (lambda (feature) (concat "'" (symbol-name feature))) + (php-ide--avilable-features) ", "))) + (cl-loop for feature in ide-features + for ide-plist = (cdr-safe (assq feature php-ide-feature-alist)) + do (if (null ide-plist) + (message "Please set `php-ide-feature' variable in .dir-locals.el or custom variable") + (if php-ide-mode + (php-ide--activate-buffer feature ide-plist) + (php-ide--deactivate-buffer ide-plist)))))) + +;;;###autoload +(defun php-ide-turn-on () + "Turn on PHP IDE-FEATURES and execute `php-ide-mode'." + (unless php-ide-features + (user-error "No PHP-IDE feature is installed. Install the lsp-mode, eglot or phpactor package")) + (php-ide-mode +1)) + +(defun php-ide--activate-buffer (name ide-plist) + "Activate php-ide implementation by NAME and IDE-PLIST." + (unless (funcall (plist-get ide-plist :test)) + (user-error "PHP-IDE feature `%s' is not available" name)) + (funcall (plist-get ide-plist :activate))) + +(defun php-ide--deactivate-buffer (ide-plist) + "Deactivate php-ide implementation by IDE-PLIST." + (funcall (plist-get ide-plist :deactivate))) + +(defun php-ide--avilable-features () + "Return list of available PHP-IDE features." + (cl-loop for (ide . plist) in php-ide-feature-alist + if (funcall (plist-get plist :test)) + collect ide)) + +(provide 'php-ide) +;;; php-ide.el ends here From e45fa0766f277df50b1b5a8bda2d8ac49d42cabd Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Mon, 31 Oct 2022 02:35:42 +0900 Subject: [PATCH 4/9] Add lsp-bridge --- lisp/php-ide.el | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lisp/php-ide.el b/lisp/php-ide.el index e19de0b2..1342c156 100644 --- a/lisp/php-ide.el +++ b/lisp/php-ide.el @@ -43,6 +43,8 @@ ;; Does not launch any IDE features. ;; - eglot ;; https://github.com/joaotavora/eglot +;; - lsp-bridge +;; https://github.com/manateelazycat/lsp-bridge ;; - lsp-mode ;; https://emacs-lsp.github.io/lsp-mode/ ;; https://github.com/emacs-lsp/lsp-mode @@ -88,6 +90,7 @@ (require 'cl-lib) (require 'php-ide-phpactor) (defvar eglot-server-programs) + (declare-function lsp-bridge-mode "ext:lsp-bridge" ()) (declare-function eglot-ensure "ext:eglot" ()) (declare-function eglot--managed-mode-off "ext:eglot" ()) (declare-function phpactor--find-executable "ext:phpactor" ())) @@ -102,6 +105,9 @@ (eglot :test (lambda () (and (require 'eglot nil t) (featurep 'eglot))) :activate eglot-ensure :deactivate eglot--managed-mode-off) + (lsp-bridge :test (lambda () (and (require 'lsp-bridge nil t) (featurep 'lsp-bridge))) + :activate (lambda () (lsp-bridge-mode +1)) + :deactivate (lambda () (lsp-bridge-mode -1))) (lsp-mode :test (lambda () (and (require 'lsp nil t) (featurep 'lsp))) :activate lsp :deactivate lsp-workspace-shutdown))) @@ -161,7 +167,7 @@ (defun php-ide-turn-on () "Turn on PHP IDE-FEATURES and execute `php-ide-mode'." (unless php-ide-features - (user-error "No PHP-IDE feature is installed. Install the lsp-mode, eglot or phpactor package")) + (user-error "No PHP-IDE feature is installed. Install the lsp-mode, lsp-bridge, eglot or phpactor package")) (php-ide-mode +1)) (defun php-ide--activate-buffer (name ide-plist) From 6d4ca45093060ad320b9a9dfc197098953b89d63 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Fri, 4 Nov 2022 02:18:00 +0900 Subject: [PATCH 5/9] Add php-ide-mode-hooks --- lisp/php-ide.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/php-ide.el b/lisp/php-ide.el index 1342c156..c0bf2e68 100644 --- a/lisp/php-ide.el +++ b/lisp/php-ide.el @@ -143,6 +143,8 @@ :type 'string :safe #'stringp) +(defvar php-ide-mode-hooks nil) + ;;;###autoload (define-minor-mode php-ide-mode "Minor mode for integrate IDE-like tools." @@ -155,6 +157,7 @@ ide-features (mapconcat (lambda (feature) (concat "'" (symbol-name feature))) (php-ide--avilable-features) ", "))) + (run-hooks 'php-ide-mode-hooks) (cl-loop for feature in ide-features for ide-plist = (cdr-safe (assq feature php-ide-feature-alist)) do (if (null ide-plist) From 91cd91a107bca6a0ad1b55d3ac05467f744b2e28 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Wed, 4 Jan 2023 23:00:54 +0900 Subject: [PATCH 6/9] Remove php-eglot.el --- Cask | 1 - Makefile | 1 - lisp/php-eglot.el | 116 ---------------------------------------------- 3 files changed, 118 deletions(-) delete mode 100644 lisp/php-eglot.el diff --git a/Cask b/Cask index 0e8d0585..a52d38fa 100644 --- a/Cask +++ b/Cask @@ -7,7 +7,6 @@ "lisp/php.el" "lisp/php-complete.el" "lisp/php-defs.el" - "lisp/php-eglot.el" "lisp/php-face.el" "lisp/php-format.el" "lisp/php-project.el" diff --git a/Makefile b/Makefile index 42db81da..77474be1 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ ELS = lisp/php.el ELS += lisp/php-align.el ELS += lisp/php-complete.el ELS += lisp/php-defs.el -ELS += lisp/php-eglot.el ELS += lisp/php-face.el ELS += lisp/php-flymake.el ELS += lisp/php-format.el diff --git a/lisp/php-eglot.el b/lisp/php-eglot.el deleted file mode 100644 index 6a7875f3..00000000 --- a/lisp/php-eglot.el +++ /dev/null @@ -1,116 +0,0 @@ -;;; php-eglot.el --- Eglot enhancement for PHP development -*- lexical-binding: t; -*- - -;; Copyright (C) 2023 Friends of Emacs-PHP development - -;; Author: USAMI Kenta -;; Keywords: tools, files -;; URL: https://github.com/emacs-php/php-mode -;; Version: 1.24.0 -;; License: GPL-3.0-or-later - -;; 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 . - -;;; Commentary: - -;; PHP Mode integrates Eglot . -;; -;; **Note**: -;; This feature is under development and experimental. -;; All of these functions, modes and terms are subject to change without notice. -;; -;; ## Configuration -;; -;; Put follows code into your .emacs (~/.emacs.d/init.el) file: -;; -;; (add-to-list 'eglot-server-programs ((php-mode phps-mode) . php-eglot-server-program)) -;; -;; ### For per project configuration -;; -;; Put follows code into .dir-locals.el in project directory: -;; -;; ((nil (php-project-root . git) -;; (php-eglot-executable . ("psalm-language-server")) -;; ;; or (php-eglot-executable . ("php" "vendor/bin/path/to/server")) -;; )) -;; -;; If you can't put .dir-locals.el in your project directory, consider the sidecar-locals package. -;; https://melpa.org/#/sidecar-locals -;; https://codeberg.org/ideasman42/emacs-sidecar-locals -;; - -;;; Code: -(require 'cl-lib) -(require 'php-project) -(require 'eglot nil t) -(require 'phpactor nil t) - -(eval-when-compile - (defvar eglot-server-programs) - (defvar eglot--managed-mode) - (declare-function eglot-ensure "ext:eglot" ()) - (declare-function phpactor--find-executable "ext:phpactor" ())) - -(defvar php-eglot-lsp-command-alist - '((intelephense "intelephense" "--stdio") - (phpactor . (lambda () (list (if (require 'phpactor nil t) - (phpactor--find-executable) - "phpactor")))))) - -(defgroup php-eglot nil - "Eglot PHP integration." - :tag "PHP-Eglot" - :prefix "php-eglot-" - :group 'eglot - :group 'php) - -;;;###autoload -(defcustom php-eglot-executable nil - "Command name or path to the command of Eglot LSP executable." - :tag "Php-Eglot Executable" - :group 'php-eglot - :type '(choice - (const intelephense) - (const phpactor) - string (repeat string)) - :safe (lambda (v) (cond - ((stringp v) (file-exists-p v)) - ((listp v) (cl-every #'stringp v)) - ((assq v php-eglot-lsp-command-alist))))) - -;;;###autoload -(defun php-eglot-server-program () - "Return a list of command to execute LSP Server." - (cond - ((stringp php-eglot-executable) (list php-eglot-executable)) - ((listp php-eglot-executable) php-eglot-executable) - ((when-let (command (assq php-eglot-executable php-eglot-lsp-command-alist)) - (cond - ((functionp command) (funcall command)) - ((listp command) command)))))) - -(defun php-eglot-ensure () - "Start PHP-specific Eglot session for current buffer if there isn't one." - (when-let (server-program (php-eglot-server-program)) - (setq-local eglot-server-programs (list (cons major-mode server-program)))) - (setq-local project-find-functions (list #'php-project-project-find-function)) - (add-function :after (local 'eglot--managed-mode) #'php-eglot--eglot--managed-mode-after) - (eglot-ensure)) - -(defun php-eglot--eglot--managed-mode-after (&optional _arg) - "Rollback variables when turning off `eglot--managed-mode'." - (unless eglot--managed-mode - (setq-local eglot-server-programs (default-value 'eglot-server-programs)))) - -(provide 'php-eglot) -;;; php-eglot.el ends here From 657a7b803d5870f2e0cdd83fdb745cbfdac808d2 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Wed, 4 Jan 2023 22:58:09 +0900 Subject: [PATCH 7/9] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de0f8d11..21fa2d8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ All notable changes of the PHP Mode 1.19.1 release series are documented in this * **Net feature**: `php-format` ([#731]) * Add `php-format-project` and `php-format-this-buffer-file` commands * Add `php-format-auto-mode` minor mode + * **Experimental feature: `php-ide`** ([#709]) + * Add `php-ide-phpactor` as simple IDE feature without LSP clients + * Add `php-ide-mode` minor mode for binding IDE-like features ### Fixed @@ -19,6 +22,7 @@ All notable changes of the PHP Mode 1.19.1 release series are documented in this * No longer highlights `'link` in PHPDoc ([#724]) * Please use `goto-address-prog-mode` minor mode +[#709]: https://github.com/emacs-php/php-mode/pull/709 [#724]: https://github.com/emacs-php/php-mode/pull/724 [#726]: https://github.com/emacs-php/php-mode/pull/726 [#731]: https://github.com/emacs-php/php-mode/pull/731 From a01bb220bfa1bf3991dbc79d50ea49342d7a6833 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Thu, 5 Jan 2023 02:52:40 +0900 Subject: [PATCH 8/9] Add php-ide-eglot-server-program command --- lisp/php-ide.el | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/lisp/php-ide.el b/lisp/php-ide.el index c0bf2e68..8d6cc758 100644 --- a/lisp/php-ide.el +++ b/lisp/php-ide.el @@ -84,10 +84,10 @@ ;; ;;; Code: +(require 'cl-lib) (require 'php-project) (eval-when-compile - (require 'cl-lib) (require 'php-ide-phpactor) (defvar eglot-server-programs) (declare-function lsp-bridge-mode "ext:lsp-bridge" ()) @@ -136,6 +136,31 @@ :safe (lambda (v) (cl-loop for feature in (if (listp v) v (list v)) always (symbolp feature)))) +;;;###autoload +(defcustom php-ide-eglot-executable nil + "Command name or path to the command of Eglot LSP executable." + :tag "PHP-IDE Eglot Executable" + :group 'php-ide + :type '(choice + (const intelephense) + (const phpactor) + string (repeat string)) + :safe (lambda (v) (cond + ((stringp v) (file-exists-p v)) + ((listp v) (cl-every #'stringp v)) + ((assq v php-ide-lsp-command-alist))))) + +;;;###autoload +(defun php-ide-eglot-server-program () + "Return a list of command to execute LSP Server." + (cond + ((stringp php-ide-eglot-executable) (list php-ide-eglot-executable)) + ((listp php-ide-eglot-executable) php-ide-eglot-executable) + ((when-let (command (assq php-ide-eglot-executable php-ide-lsp-command-alist)) + (cond + ((functionp command) (funcall command)) + ((listp command) command)))))) + (defcustom php-ide-mode-lighter " PHP-IDE" "A symbol of PHP-IDE feature." :tag "PHP-IDE Mode Lighter" From ece3dd51ce8ef349335042097a836ef4cd2ff03a Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Sun, 19 Mar 2023 05:55:50 +0900 Subject: [PATCH 9/9] Add php-ide-mode-functions instead of php-ide-mode-hooks --- lisp/php-ide.el | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/lisp/php-ide.el b/lisp/php-ide.el index 8d6cc758..bd61e6ad 100644 --- a/lisp/php-ide.el +++ b/lisp/php-ide.el @@ -57,9 +57,18 @@ ;; ;; Put follows code into your .emacs (~/.emacs.d/init.el) file: ;; -;; (defun my-php-mode-setup () +;; (defun init-php-mode-setup () ;; (add-hook 'hack-local-variables-hook #'php-ide-mode t t)) ;; +;; (defun init-php-ide-mode-setup (feature activate) +;; (pcase feature +;; (`lsp-bridge +;; (if activate +;; (progn (yas-minor-mode +1) +;; (corfu-mode -1)) +;; (yas-minor-mode -1) +;; (corfu-mode +1))))) +;; ;; (with-eval-after-load 'php-ide ;; (custom-set-variables ;; '(php-ide-features . 'eglot) ;; and/or 'none, 'phpactor, 'lsp-mode @@ -67,7 +76,8 @@ ;; ;; If you want to hide php-ide-mode from the mode line, set an empty string ;; '(php-ide-mode-lighter "")) ;; -;; (add-hook 'php-mode #'my-php-mode-setup)) +;; (add-hook 'php-mode-hook #'init-php-mode-setup) +;; (add-hook 'php-ide-mode-functions #'init-php-ide-mode-setup)) ;; ;; If you don't enable IDE support by default, set '(php-ide-feature 'none) ;; @@ -168,7 +178,19 @@ :type 'string :safe #'stringp) -(defvar php-ide-mode-hooks nil) +(defcustom php-ide-mode-functions nil + "Hook functions called when before activating or deactivating PHP-IDE. +Notice that two arguments (FEATURE ACTIVATE) are given. + +FEATURE: A symbol, like 'lsp-mode. +ACTIVATE: T is given when activeting, NIL when deactivating PHP-IDE." + :tag "PHP-IDE Mode Functions" + :group 'php-ide + :type '(repeat function) + :safe (lambda (functions) + (and (listp functions) + (cl-loop for function in functions + always (functionp function))))) ;;;###autoload (define-minor-mode php-ide-mode @@ -182,11 +204,11 @@ ide-features (mapconcat (lambda (feature) (concat "'" (symbol-name feature))) (php-ide--avilable-features) ", "))) - (run-hooks 'php-ide-mode-hooks) (cl-loop for feature in ide-features for ide-plist = (cdr-safe (assq feature php-ide-feature-alist)) do (if (null ide-plist) (message "Please set `php-ide-feature' variable in .dir-locals.el or custom variable") + (run-hook-with-args 'php-ide-mode-functions feature php-ide-mode) (if php-ide-mode (php-ide--activate-buffer feature ide-plist) (php-ide--deactivate-buffer ide-plist))))))