branch: elpa/php-mode commit 6049ad74539fa6fab59234ccc76dcb70ec4ce1ae Author: USAMI Kenta <tad...@zonu.me> Commit: USAMI Kenta <tad...@zonu.me>
Add php-complete.el --- CHANGELOG.md | 6 +++ Makefile | 4 +- lisp/php-complete.el | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be5eb0448c..426174e365 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes of the PHP Mode 1.19.1 release series are documented in this ## Unreleased +### Added + + * **New feature: `php-complete`** + * Add `php-complete-complete-function` to autocomplete function names ([#708]) + ### Changed * 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 [#703]: https://github.com/emacs-php/php-mode/pull/703 [#704]: https://github.com/emacs-php/php-mode/pull/704 [#707]: https://github.com/emacs-php/php-mode/pull/707 +[#708]: https://github.com/emacs-php/php-mode/pull/708 ## [1.24.1] - 2022-10-08 diff --git a/Makefile b/Makefile index 42fcf641e5..97922d2a50 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ EMACS ?= emacs CASK ?= cask -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 +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 AUTOLOADS = php-mode-autoloads.el ELCS = $(ELS:.el=.elc) @@ -24,7 +24,7 @@ AUTHORS.md: etc/git/AUTHORS.md.in .mailmap autoloads: $(AUTOLOADS) -$(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 +$(AUTOLOADS): $(ELS) $(EMACS) --batch -L lisp/ --eval \ "(let ((user-emacs-directory default-directory)) \ (require 'package) \ diff --git a/lisp/php-complete.el b/lisp/php-complete.el new file mode 100644 index 0000000000..588efa7852 --- /dev/null +++ b/lisp/php-complete.el @@ -0,0 +1,124 @@ +;;; php-complete.el --- PHP auto-compiletion functions -*- lexical-binding: t; -*- + +;; Copyright (C) 2022 Friends of Emacs-PHP development +;; Copyright (C) 2021, 2022 Free Software Foundation, Inc. + +;; Author: USAMI Kenta <tad...@zonu.me> + +;; Created: 18 Sep 2022 +;; Version: 1.24.1 +;; Keywords: languages, 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: + +;; Provide auto-compiletion functions. + +;; These functions are copied function from GNU ELPA. +;; +;; - cape--table-with-properties (cape.el) +;; - cape--bounds (cape.el) +;; - cape--interactive (cape.el) + +;;; Code: +(eval-when-compile + (require 'cl-lib)) +(require 'php) +(require 'php-defs) + +;;;###autoload +(defgroup php-complete nil + "Auto completion for PHP edition." + :tag "PHP Completion" + :group 'php-mode) + +;;;###autoload +(defcustom php-complete-function-modules '(bcmath core gmp libxml intl mbstring pcntl posix sodium xml xmlwriter) + "Module names for function names completion." + :tag "PHP Complete Function Modules" + :type (eval-when-compile `(set ,@(mapcar (lambda (elm) (list 'const (car elm))) + php-defs-functions-alist))) + :safe (lambda (value) (and (listp value) (cl-loop for v in values + always (assq v php-defs-functions-alist)))) + :group 'php-complete) + +;;; Cape functions: + +;; These functions are copied from cape.el package. https://github.com/minad/cape +;; Thanks to original author Daniel Mendler (@minad) + +(cl-defun php-complete--cape-table-with-properties (table &key category (sort t) &allow-other-keys) + "Create completion TABLE with properties. +CATEGORY is the optional completion category. +SORT should be nil to disable sorting." + (if (or (not table) (and (not category) sort)) + table + (let ((metadata `(metadata + ,@(and category `((category . ,category))) + ,@(and (not sort) '((display-sort-function . identity) + (cycle-sort-function . identity)))))) + (lambda (str pred action) + (if (eq action 'metadata) + metadata + (complete-with-action action table str pred)))))) + +(defun php-complete--cape-bounds (thing) + "Return bounds of THING." + (or (bounds-of-thing-at-point thing) (cons (point) (point)))) + +(defun php-complete--cape-interactive (capf) + "Complete with CAPF." + (let ((completion-at-point-functions (list capf))) + (or (completion-at-point) (user-error "%s: No completions" capf)))) + +;;; Variables: +(defvar php-complete--functions-cache (make-hash-table :test #'equal)) + +;;; Data source functions: +(defun php-complete--functions () + "Return PHP function names." + (let* ((modules (sort php-complete-function-modules #'string<)) + (functions (gethash modules php-complete--functions-cache))) + (unless functions + (setq functions (sort (cl-loop for module in modules + append (assq module php-defs-functions-alist)) + #'string<)) + (puthash modules functions php-complete--functions-cache)) + functions)) + +;;; Compiletion function: + +;;;###autoload +(defun php-complete-complete-function (&optional interactive) + "Complete PHP keyword at point. + +If INTERACTIVE is nil the function acts like a capf." + (interactive (list t)) + (if interactive + (php-complete--cape-interactive #'php-complete-complete-function) + (let ((bounds (php-complete--cape-bounds 'symbol)) + (tokens (nreverse (php-leading-tokens 2)))) + `(,(car bounds) ,(cdr bounds) + ,(php-complete--cape-table-with-properties + (unless (or (member (nth 0 tokens) '("->" "::")) + (string-prefix-p "$" (nth 1 tokens))) + (php-complete--functions)) + :category 'cape-keyword) + :annotation-function (lambda (_) " PHP functions") + :company-kind (lambda (_) 'keyword) + :exclusive 'no)))) + +(provide 'php-complete) +;;; php-complete.el ends here