Skip to content

Commit bb5bec3

Browse files
committed
Add php-ide.el
1 parent acde9ab commit bb5bec3

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

Cask

+2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
"lisp/php-project.el"
1414
"lisp/php-local-manual.el"
1515
"lisp/php-ide-phpactor.el"
16+
"lisp/php-ide.el"
1617
"lisp/php-mode-debug.el")
1718

1819
(development
20+
;;(depends-on "lsp-mode")
1921
(depends-on "phpactor")
2022
(depends-on "pkg-info")
2123
(depends-on "projectile")

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ELS += lisp/php-face.el
99
ELS += lisp/php-flymake.el
1010
ELS += lisp/php-format.el
1111
ELS += lisp/php-ide-phpactor.el
12+
ELS += lisp/php-ide.el
1213
ELS += lisp/php-local-manual.el
1314
ELS += lisp/php-mode-debug.el
1415
ELS += lisp/php-mode.el

lisp/php-ide.el

+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
;;; php-ide.el --- IDE-like UI support for PHP development -*- lexical-binding: t; -*-
2+
3+
;; Copyright (C) 2023 Friends of Emacs-PHP development
4+
5+
;; Author: USAMI Kenta <[email protected]>
6+
;; Keywords: tools, files
7+
;; URL: https://github.com/emacs-php/php-mode
8+
;; Version: 1.24.0
9+
;; License: GPL-3.0-or-later
10+
11+
;; This program is free software; you can redistribute it and/or modify
12+
;; it under the terms of the GNU General Public License as published by
13+
;; the Free Software Foundation, either version 3 of the License, or
14+
;; (at your option) any later version.
15+
16+
;; This program is distributed in the hope that it will be useful,
17+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
;; GNU General Public License for more details.
20+
21+
;; You should have received a copy of the GNU General Public License
22+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
23+
24+
;;; Commentary:
25+
26+
;; PHP Mode integrates LSP Mode (lsp-mode), Phpactor (phpactor.el) and IDE-like tools.
27+
;;
28+
;; **Note**:
29+
;; This feature is under development and experimental.
30+
;; All of these functions, modes and terms are subject to change without notice.
31+
;;
32+
;; ## Motivations
33+
;;
34+
;; There are some IDE-like features / packages for PHP development.
35+
;; PHP-IDE bridges projects and their IDE-like features.
36+
;;
37+
;; ## IDE Features
38+
;;
39+
;; We don't recommend features, but bundle some feature bridges.
40+
;; They are sorted alphabetically except "none."
41+
;;
42+
;; - none
43+
;; Does not launch any IDE features.
44+
;; - eglot
45+
;; https://github.com/joaotavora/eglot
46+
;; - lsp-mode
47+
;; https://emacs-lsp.github.io/lsp-mode/
48+
;; https://github.com/emacs-lsp/lsp-mode
49+
;; - phpactor
50+
;; https://phpactor.readthedocs.io/
51+
;; https://github.com/phpactor/phpactor
52+
;; https://github.com/emacs-php/phpactor.el
53+
;;
54+
;; ## Configuration
55+
;;
56+
;; Put follows code into your .emacs (~/.emacs.d/init.el) file:
57+
;;
58+
;; (defun my-php-mode-setup ()
59+
;; (add-hook 'hack-local-variables-hook #'php-ide-mode t t))
60+
;;
61+
;; (with-eval-after-load 'php-ide
62+
;; (custom-set-variables
63+
;; '(php-ide-features . 'eglot) ;; and/or 'none, 'phpactor, 'lsp-mode
64+
;; '(php-ide-eglot-executable "psalm-language-server") ;; or "intelephense", '("php" "vendor/bin/path/to/server")
65+
;; ;; If you want to hide php-ide-mode from the mode line, set an empty string
66+
;; '(php-ide-mode-lighter ""))
67+
;;
68+
;; (add-hook 'php-mode #'my-php-mode-setup))
69+
;;
70+
;; If you don't enable IDE support by default, set '(php-ide-feature 'none)
71+
;;
72+
;; ### For per project configuration
73+
;;
74+
;; Put follows code into .dir-locals.el in project directory:
75+
;;
76+
;; ((nil (php-project-root . git)
77+
;; (php-ide-features . (lsp-mode))))
78+
;;
79+
;; If you can't put .dir-locals.el in your project directory, consider the sidecar-locals package.
80+
;; https://melpa.org/#/sidecar-locals
81+
;; https://codeberg.org/ideasman42/emacs-sidecar-locals
82+
;;
83+
84+
;;; Code:
85+
(require 'php-project)
86+
87+
(eval-when-compile
88+
(require 'cl-lib)
89+
(require 'php-ide-phpactor)
90+
(defvar eglot-server-programs)
91+
(declare-function eglot-ensure "ext:eglot" ())
92+
(declare-function eglot--managed-mode-off "ext:eglot" ())
93+
(declare-function phpactor--find-executable "ext:phpactor" ()))
94+
95+
(defvar php-ide-feature-alist
96+
'((none :test (lambda () t)
97+
:activate (lambda () t)
98+
:deactivate (lambda () t))
99+
(phpactor :test (lambda () (and (require 'phpactor nil t) (featurep 'phpactor)))
100+
:activate php-ide-phpactor-activate
101+
:deactivate php-ide-phpactor-activate)
102+
(eglot :test (lambda () (and (require 'eglot nil t) (featurep 'eglot)))
103+
:activate eglot-ensure
104+
:deactivate eglot--managed-mode-off)
105+
(lsp-mode :test (lambda () (and (require 'lsp nil t) (featurep 'lsp)))
106+
:activate lsp
107+
:deactivate lsp-workspace-shutdown)))
108+
109+
(defvar php-ide-lsp-command-alist
110+
'((intelephense "intelephense" "--stdio")
111+
(phpactor . (lambda () (list (if (fboundp 'phpactor--find-executable)
112+
(phpactor--find-executable)
113+
"phpactor")
114+
"language-server")))))
115+
116+
(defgroup php-ide nil
117+
"IDE-like support for PHP developing."
118+
:tag "PHP-IDE"
119+
:prefix "php-ide-"
120+
:group 'php)
121+
122+
;;;###autoload
123+
(defcustom php-ide-features nil
124+
"A set of PHP-IDE features symbol."
125+
:tag "PHP-IDE Feature"
126+
:group 'php-ide
127+
:type `(set ,@(mapcar (lambda (feature) (list 'const (car feature)))
128+
php-ide-feature-alist)
129+
symbol)
130+
:safe (lambda (v) (cl-loop for feature in (if (listp v) v (list v))
131+
always (symbolp feature))))
132+
133+
(defcustom php-ide-mode-lighter " PHP-IDE"
134+
"A symbol of PHP-IDE feature."
135+
:tag "PHP-IDE Mode Lighter"
136+
:group 'php-ide
137+
:type 'string
138+
:safe #'stringp)
139+
140+
;;;###autoload
141+
(define-minor-mode php-ide-mode
142+
"Minor mode for integrate IDE-like tools."
143+
:lighter php-ide-mode-lighter
144+
(let ((ide-features php-ide-features))
145+
(when-let (unavailable-features (cl-loop for feature in ide-features
146+
unless (assq feature php-ide-feature-alist)
147+
collect feature))
148+
(user-error "%s includes unavailable PHP-IDE features. (available features are: %s)"
149+
ide-features
150+
(mapconcat (lambda (feature) (concat "'" (symbol-name feature)))
151+
(php-ide--avilable-features) ", ")))
152+
(cl-loop for feature in ide-features
153+
for ide-plist = (cdr-safe (assq feature php-ide-feature-alist))
154+
do (if (null ide-plist)
155+
(message "Please set `php-ide-feature' variable in .dir-locals.el or custom variable")
156+
(if php-ide-mode
157+
(php-ide--activate-buffer feature ide-plist)
158+
(php-ide--deactivate-buffer ide-plist))))))
159+
160+
;;;###autoload
161+
(defun php-ide-turn-on ()
162+
"Turn on PHP IDE-FEATURES and execute `php-ide-mode'."
163+
(unless php-ide-features
164+
(user-error "No PHP-IDE feature is installed. Install the lsp-mode, eglot or phpactor package"))
165+
(php-ide-mode +1))
166+
167+
(defun php-ide--activate-buffer (name ide-plist)
168+
"Activate php-ide implementation by NAME and IDE-PLIST."
169+
(unless (funcall (plist-get ide-plist :test))
170+
(user-error "PHP-IDE feature `%s' is not available" name))
171+
(funcall (plist-get ide-plist :activate)))
172+
173+
(defun php-ide--deactivate-buffer (ide-plist)
174+
"Deactivate php-ide implementation by IDE-PLIST."
175+
(funcall (plist-get ide-plist :deactivate)))
176+
177+
(defun php-ide--avilable-features ()
178+
"Return list of available PHP-IDE features."
179+
(cl-loop for (ide . plist) in php-ide-feature-alist
180+
if (funcall (plist-get plist :test))
181+
collect ide))
182+
183+
(provide 'php-ide)
184+
;;; php-ide.el ends here

0 commit comments

Comments
 (0)