|
1 | 1 | ;;; phpactor.el --- Interface to Phpactor -*- lexical-binding: t; -*-
|
2 | 2 |
|
3 |
| -;; Copyright (C) 2024 Friends of Emacs-PHP development |
| 3 | +;; Copyright (C) 2025 Friends of Emacs-PHP development |
4 | 4 |
|
5 | 5 | ;; Author: USAMI Kenta <tadsan@zonu.me>
|
6 | 6 | ;; Mikael Kermorgant <mikael@kgtech.fi>
|
7 | 7 | ;; Created: 8 Apr 2018
|
8 | 8 | ;; Version: 0.1.0
|
9 | 9 | ;; Keywords: tools, php
|
10 |
| -;; Package-Requires: ((emacs "25.1") (f "0.17") (php-runtime "0.2") (composer "0.2.0") (async "1.9.3")) |
| 10 | +;; Package-Requires: ((emacs "26.1") (f "0.17") (php-runtime "0.2") (composer "0.2.0") (async "1.9.3")) |
11 | 11 | ;; URL: https://github.com/emacs-php/phpactor.el
|
12 | 12 | ;; License: GPL-3.0-or-later
|
13 | 13 |
|
|
93 | 93 | (defvar phpactor-after-update-file-hook nil
|
94 | 94 | "Hook called after the file is updated by phpactor.")
|
95 | 95 |
|
| 96 | +(defvar phpactor--index-buffer-name-template "*Phpactor index %s*") |
| 97 | + |
96 | 98 | ;;; Constants
|
97 | 99 | (defconst phpactor-command-name "phpactor")
|
98 | 100 | (defconst phpactor--supported-rpc-version "1.0.0")
|
@@ -241,6 +243,51 @@ have to ensure a compatible version of phpactor is used."
|
241 | 243 | #'shell-command
|
242 | 244 | #'shell-command-to-string)
|
243 | 245 | (phpactor--make-command-string "config:dump"))))
|
| 246 | + |
| 247 | +(defun phpactor-index-symbols-buffer (force-update) |
| 248 | + "Run the Phpactor `index:search' command and return the buffer. |
| 249 | +If FORCE-UPDATE is non-nil (e.g., via a prefix argument > 1), |
| 250 | +regenerate the index and update the buffer. |
| 251 | +Otherwise, use cached results if the buffer already exists and is populated." |
| 252 | + (interactive (list (> (prefix-numeric-value current-prefix-arg) 1))) |
| 253 | + (let* ((default-directory (phpactor-get-working-dir)) |
| 254 | + (buf-name (format phpactor--index-buffer-name-template |
| 255 | + (abbreviate-file-name default-directory))) |
| 256 | + (buf (get-buffer-create buf-name)) |
| 257 | + original-hash new-hash) |
| 258 | + (with-current-buffer buf |
| 259 | + (when (or force-update (zerop (buffer-size))) |
| 260 | + (widen) |
| 261 | + (setq original-hash (buffer-hash)) |
| 262 | + (erase-buffer) |
| 263 | + (shell-command (phpactor--make-command-string "index:search") (current-buffer)) |
| 264 | + (sort-lines nil (point-min) (point-max)) |
| 265 | + (setq new-hash (buffer-hash)))) |
| 266 | + (prog1 buf |
| 267 | + (when (called-interactively-p 'interactive) |
| 268 | + (message "Buffer %S has %s" buf-name (cond ((null original-hash) "loaded from cache") |
| 269 | + ((equal original-hash (buffer-hash)) "updated") |
| 270 | + ("not updated"))))))) |
| 271 | + |
| 272 | +(defun phpactor--index-symbols-as-alist () |
| 273 | + "Return result of Phpactor `index:search' command as alist." |
| 274 | + (with-current-buffer (phpactor-index-symbols-buffer nil) |
| 275 | + (goto-char (point-min)) |
| 276 | + (cl-loop while (re-search-forward "^\\(class\\|function\\|constant\\) # \\([^ |
| 277 | +(]+\\)\\( (\\(?:interface\\|class\\|trait\\))\\)?$" nil t) |
| 278 | + collect (cons (match-string 0) (match-string 2))))) |
| 279 | + |
| 280 | +(defun phpactor-index:query (identifier) |
| 281 | + "Execute Phpactor `index:query' sub command with IDENTIFIER." |
| 282 | + (interactive (list (let* ((alist (phpactor--index-symbols-as-alist)) |
| 283 | + (input (completing-read "Identifier: " alist))) |
| 284 | + (alist-get input alist nil nil #'equal)))) |
| 285 | + (let ((default-directory (phpactor-get-working-dir))) |
| 286 | + (funcall |
| 287 | + (if (called-interactively-p 'interactive) |
| 288 | + #'compile |
| 289 | + #'shell-command-to-string) |
| 290 | + (phpactor--make-command-string "index:query" identifier)))) |
244 | 291 |
|
245 | 292 | ;; Phpactor RPC
|
246 | 293 | (defun phpactor--rpc (action arguments)
|
|
0 commit comments