Skip to content

Commit

Permalink
Add php-ide.el
Browse files Browse the repository at this point in the history
  • Loading branch information
zonuexe committed Oct 10, 2022
1 parent 7dcb869 commit f8d5178
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cask
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,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")
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ ELS += lisp/php-complete.el
ELS += lisp/php-defs.el
ELS += lisp/php-face.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
Expand Down
188 changes: 188 additions & 0 deletions lisp/php-ide.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
;;; php-ide.el --- IDE-like UI support for PHP development -*- lexical-binding: t; -*-

;; Copyright (C) 2022 Friends of Emacs-PHP development

;; Author: USAMI Kenta <[email protected]>
;; 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 <https://www.gnu.org/licenses/>.

;;; 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 ""))
;;
;; ;; Only Eglot users
;; (add-to-list 'php-ide-eglot-executable '(php-mode . php-ide-eglot-server-program))
;;
;; (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-eglot-executable . ("psalm-language-server"))
;; ;; or (php-ide-eglot-executable . ("php" "vendor/bin/path/to/server"))
;; (php-ide-feature . 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"))))))

(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) (if (listp v)
(cl-loop for feature in v
always (assq feature php-ide-feature-alist))
(assq v php-ide-feature-alist))))

(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 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 (ide-plist)
"Activate php-ide implementation by IDE-PLIST."
(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

0 comments on commit f8d5178

Please sign in to comment.