Skip to content

Commit 7e4905a

Browse files
authored
Merge pull request #708 from emacs-php/feature/php-completion
New feature: php-completion.el
2 parents 6513efa + 8366639 commit 7e4905a

11 files changed

+5946
-22
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/.keg/*
66
/.php-cs-fixer.cache
77
php-mode-autoloads.el
8+
php_manual_en.json

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes of the PHP Mode 1.19.1 release series are documented in this
44

55
## Unreleased
66

7+
### Added
8+
9+
* **New feature: `php-complete`**
10+
* Add `php-complete-complete-function` to autocomplete function names ([#708])
11+
712
### Changed
813

914
* Make continued expressions inside lists (arguments and arrays, etc.) have the same indent width as outside the list ([#703])
@@ -16,6 +21,7 @@ All notable changes of the PHP Mode 1.19.1 release series are documented in this
1621
[#703]: https://github.com/emacs-php/php-mode/pull/703
1722
[#704]: https://github.com/emacs-php/php-mode/pull/704
1823
[#707]: https://github.com/emacs-php/php-mode/pull/707
24+
[#708]: https://github.com/emacs-php/php-mode/pull/708
1925

2026
## [1.24.1] - 2022-10-08
2127

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
EMACS ?= emacs
22
CASK ?= cask
3-
ELS = lisp/php.el lisp/php-align.el lisp/php-face.el lisp/php-project.el lisp/php-local-manual.el lisp/php-mode.el lisp/php-mode-debug.el
3+
ELS = lisp/php.el lisp/php-align.el lisp/php-complete.el lisp/php-defs.el lisp/php-face.el lisp/php-project.el lisp/php-local-manual.el lisp/php-mode.el lisp/php-mode-debug.el
44
AUTOLOADS = php-mode-autoloads.el
55
ELCS = $(ELS:.el=.elc)
66

@@ -24,7 +24,7 @@ AUTHORS.md: etc/git/AUTHORS.md.in .mailmap
2424

2525
autoloads: $(AUTOLOADS)
2626

27-
$(AUTOLOADS): lisp/php.el lisp/php-align.el lisp/php-face.el lisp/php-project.el lisp/php-local-manual.el lisp/php-mode-debug.el lisp/php-mode.el
27+
$(AUTOLOADS): $(ELS)
2828
$(EMACS) --batch -L lisp/ --eval \
2929
"(let ((user-emacs-directory default-directory)) \
3030
(require 'package) \

lisp/php-complete.el

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
;;; php-complete.el --- PHP auto-compiletion functions -*- lexical-binding: t; -*-
2+
3+
;; Copyright (C) 2022 Friends of Emacs-PHP development
4+
;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
5+
6+
;; Author: USAMI Kenta <[email protected]>
7+
8+
;; Created: 18 Sep 2022
9+
;; Version: 1.24.1
10+
;; Keywords: languages, php
11+
12+
;; This program is free software; you can redistribute it and/or modify
13+
;; it under the terms of the GNU General Public License as published by
14+
;; the Free Software Foundation, either version 3 of the License, or
15+
;; (at your option) any later version.
16+
17+
;; This program is distributed in the hope that it will be useful,
18+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
;; GNU General Public License for more details.
21+
22+
;; You should have received a copy of the GNU General Public License
23+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
24+
25+
;;; Commentary:
26+
27+
;; Provide auto-compiletion functions.
28+
29+
;; These functions are copied function from GNU ELPA.
30+
;;
31+
;; - cape--table-with-properties (cape.el)
32+
;; - cape--bounds (cape.el)
33+
;; - cape--interactive (cape.el)
34+
35+
;;; Code:
36+
(eval-when-compile
37+
(require 'cl-lib))
38+
(require 'php)
39+
(require 'php-defs)
40+
41+
;;;###autoload
42+
(defgroup php-complete nil
43+
"Auto completion for PHP edition."
44+
:tag "PHP Completion"
45+
:group 'php-mode)
46+
47+
;;;###autoload
48+
(defcustom php-complete-function-modules '(bcmath core gmp libxml intl mbstring pcntl posix sodium xml xmlwriter)
49+
"Module names for function names completion."
50+
:tag "PHP Complete Function Modules"
51+
:type (eval-when-compile `(set ,@(mapcar (lambda (elm) (list 'const (car elm)))
52+
php-defs-functions-alist)))
53+
:safe (lambda (value) (and (listp value) (cl-loop for v in values
54+
always (assq v php-defs-functions-alist))))
55+
:group 'php-complete)
56+
57+
;;; Cape functions:
58+
59+
;; These functions are copied from cape.el package. https://github.com/minad/cape
60+
;; Thanks to original author Daniel Mendler (@minad)
61+
62+
(cl-defun php-complete--cape-table-with-properties (table &key category (sort t) &allow-other-keys)
63+
"Create completion TABLE with properties.
64+
CATEGORY is the optional completion category.
65+
SORT should be nil to disable sorting."
66+
(if (or (not table) (and (not category) sort))
67+
table
68+
(let ((metadata `(metadata
69+
,@(and category `((category . ,category)))
70+
,@(and (not sort) '((display-sort-function . identity)
71+
(cycle-sort-function . identity))))))
72+
(lambda (str pred action)
73+
(if (eq action 'metadata)
74+
metadata
75+
(complete-with-action action table str pred))))))
76+
77+
(defun php-complete--cape-bounds (thing)
78+
"Return bounds of THING."
79+
(or (bounds-of-thing-at-point thing) (cons (point) (point))))
80+
81+
(defun php-complete--cape-interactive (capf)
82+
"Complete with CAPF."
83+
(let ((completion-at-point-functions (list capf)))
84+
(or (completion-at-point) (user-error "%s: No completions" capf))))
85+
86+
;;; Variables:
87+
(defvar php-complete--functions-cache (make-hash-table :test #'equal))
88+
89+
;;; Data source functions:
90+
(defun php-complete--functions ()
91+
"Return PHP function names."
92+
(let* ((modules (sort php-complete-function-modules #'string<))
93+
(functions (gethash modules php-complete--functions-cache)))
94+
(unless functions
95+
(setq functions (sort (cl-loop for module in modules
96+
append (assq module php-defs-functions-alist))
97+
#'string<))
98+
(puthash modules functions php-complete--functions-cache))
99+
functions))
100+
101+
;;; Compiletion function:
102+
103+
;;;###autoload
104+
(defun php-complete-complete-function (&optional interactive)
105+
"Complete PHP keyword at point.
106+
107+
If INTERACTIVE is nil the function acts like a capf."
108+
(interactive (list t))
109+
(if interactive
110+
(php-complete--cape-interactive #'php-complete-complete-function)
111+
(let ((bounds (php-complete--cape-bounds 'symbol))
112+
(tokens (nreverse (php-leading-tokens 2))))
113+
`(,(car bounds) ,(cdr bounds)
114+
,(php-complete--cape-table-with-properties
115+
(unless (or (member (nth 0 tokens) '("->" "::"))
116+
(string-prefix-p "$" (nth 1 tokens)))
117+
(php-complete--functions))
118+
:category 'cape-keyword)
119+
:annotation-function (lambda (_) " PHP functions")
120+
:company-kind (lambda (_) 'keyword)
121+
:exclusive 'no))))
122+
123+
(provide 'php-complete)
124+
;;; php-complete.el ends here

0 commit comments

Comments
 (0)