diff options
Diffstat (limited to 'oni-php/oni-php.el')
| -rw-r--r-- | oni-php/oni-php.el | 114 |
1 files changed, 94 insertions, 20 deletions
diff --git a/oni-php/oni-php.el b/oni-php/oni-php.el index 88af7af..1415d2b 100644 --- a/oni-php/oni-php.el +++ b/oni-php/oni-php.el @@ -4,8 +4,8 @@ ;; Author: Tom Willemse <tom@ryuslash.org> ;; Keywords: local -;; Version: 2026.0107.143829 -;; Package-Requires: (php-mode oni-yasnippet oni-flycheck oni-company oni-hydra oni-smartparens ggtags fic-mode company-php rainbow-delimiters rainbow-identifiers) +;; Version: 2026.0407.170526 +;; Package-Requires: (oni-yasnippet oni-flycheck oni-company oni-hydra oni-smartparens ggtags fic-mode company-php rainbow-delimiters rainbow-identifiers) ;; 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 @@ -30,7 +30,8 @@ (require 'align) (require 'company) (require 'hydra) -(require 'php-mode) +(require 'map) +(require 'project) (require 'whitespace) (require 'yasnippet) @@ -79,7 +80,7 @@ nil for some reason." (defun oni-php-add-use (class) "Try to add a use statement for CLASS under point." - (interactive (list (symbol-name (symbol-at-point)))) + (interactive (list (thing-at-point 'symbol))) (let* ((default-directory (project-root (project-current))) (classes (read (shell-command-to-string (concat (expand-file-name "find-php-class" oni-php-scripts-dir) " " class)))) (class (cond @@ -97,19 +98,31 @@ nil for some reason." (forward-line) (insert "\n")) - (unless (search-backward class nil t) + (unless (re-search-backward (rx "use " (literal class) ";") nil t) (let ((start (point))) (insert "use " class ";\n") (pulse-momentary-highlight-region start (point))))))) +(defun oni-php--syntax-in-string-p (syntax) + "Does SYNTAX indicate point is inside a string?" + (nth 3 syntax)) + +(defun oni-php--syntax-in-comment-p (syntax) + "Does SYNTAX indicate point is inside a comment?" + (nth 4 syntax)) + +(defun oni-php--in-string-or-comment-p () + "Return whether or not point is within a string or comment." + (let ((syntax (syntax-ppss))) + (or (oni-php--syntax-in-string-p syntax) + (oni-php--syntax-in-comment-p syntax)))) + (defun oni-php-insert-dot-dwim (N) "Insert either a concatenation or access operator depending on context. Do the insert N times." (interactive "p") - (if (or (let ((syntax (syntax-ppss))) - (or (nth 3 syntax) - (nth 4 syntax))) + (if (or (oni-php--in-string-or-comment-p) (save-excursion (skip-syntax-backward " ") (nth 3 (syntax-ppss (1- (point))))) @@ -117,7 +130,11 @@ Do the insert N times." (skip-syntax-forward " ") (nth 3 (syntax-ppss (1+ (point)))))) (self-insert-command N) - (dotimes (_ N) (insert "->")))) + (let ((op (if (looking-back (rx (or "$" ")") (zero-or-more (any whitespace "\n" alnum "(" ")" "->"))) + (save-excursion (backward-paragraph) (point))) + "->" + "::"))) + (dotimes (_ N) (insert op))))) (defun oni-php-doc-comment () "Insert a PHP documentation comment at point." @@ -129,17 +146,52 @@ Do the insert N times." (indent-region start (point)) (goto-char insert-marker)))) +(defun oni-php-doc-use-comment () + "Insert a PHP documentation comment for a use statement." + (interactive) + (let ((start (point)) + (class (save-excursion + (save-match-data + (search-forward-regexp (rx "use " (group (minimal-match (zero-or-more alnum))) ";")) + (match-string 1))))) + (insert "/**\n * @use " class) + (let ((insert-marker (point-marker))) + (insert "\n */") + (indent-region start (point)) + (goto-char insert-marker)))) + (defun oni-php-comment-dwim (func &rest args) "See if a PHP documentation comment should be added and add it. Otherwise call FUNC with ARGS. This is meant as advice around ‘comment-dwim’ to make it smarter for PHP code." - (if (and (derived-mode-p 'php-mode) - (looking-back (rx (minimal-match (zero-or-more blank))) (line-beginning-position)) - (looking-at (rx (minimal-match (zero-or-more (any whitespace "\n"))) - (or (regexp php-beginning-of-defun-regexp) - (regexp php--re-classlike-pattern))))) - (oni-php-doc-comment) - (apply func args))) + (cond ((looking-at (rx (minimal-match (zero-or-more (any whitespace "\n"))) + "use ")) + (oni-php-doc-use-comment)) + ((and (derived-mode-p 'php-mode) + (not (region-active-p)) + (looking-back (rx (minimal-match (zero-or-more blank))) (line-beginning-position)) + (looking-at (rx (minimal-match (zero-or-more (any whitespace "\n"))) + (or (regexp php-beginning-of-defun-regexp) + (regexp php--re-classlike-pattern))))) + (oni-php-doc-comment)) + (t (apply func args)))) + +(defun oni-php-generate-namespace () + (string-join + (mapcar + (lambda (s) + (let ((case-fold-search nil)) + (if (string-match-p (rx upper-case) s) + s + (capitalize s)))) + (cdr (split-string + (directory-file-name + (file-name-directory + (file-relative-name + buffer-file-name + (project-root (project-current))))) + "/"))) + "\\")) (defhydra php-mode-hydra (:color blue) ("a" align-current "Align current selection")) @@ -181,7 +233,7 @@ Otherwise call FUNC with ARGS. This is meant as advice around `(php-array-arrow (regexp . ,(rx any (group (zero-or-more whitespace)) "=>" any)) (group . (1)) - (modes . '(php-mode web-mode)) + (modes . '(php-mode web-mode php-mode)) (repeat . t))) ;; The WordPress coding standards specify that multiple assignments @@ -197,7 +249,7 @@ Otherwise call FUNC with ARGS. This is meant as advice around (regexp . ,(rx any (group (zero-or-more whitespace)) "=" (zero-or-more whitespace) any)) (group . (1)) - (modes . '(php-mode web-mode)) + (modes . '(php-mode web-mode php-ts-mode)) (repeat . t))) (with-eval-after-load 'php-mode @@ -215,13 +267,25 @@ Otherwise call FUNC with ARGS. This is meant as advice around (add-to-list 'grep-files-aliases '("php" . "*.php *.inc *.module"))) (with-eval-after-load 'autoinsert - (setf (map-elt auto-insert-alist (rx "Test.php" eos)) + (setf (map-elt auto-insert-alist (rx ".php" eos)) '(nil "<?php\n" "\n" "declare(strict_types=1);\n" "\n" - "namespace " (string-join (mapcar #'capitalize (cdr (split-string (directory-file-name (file-name-directory (file-relative-name buffer-file-name (project-root (project-current))))) "/"))) "\\") ";\n" + "namespace " (oni-php-generate-namespace) ";\n" + "\n" + "class " (file-name-sans-extension (file-name-nondirectory (buffer-file-name))) "\n" + "{\n" + > _ "\n" + "}\n") + (map-elt auto-insert-alist (rx "Test.php" eos)) + '(nil + "<?php\n" + "\n" + "declare(strict_types=1);\n" + "\n" + "namespace " (oni-php-generate-namespace) ";\n" "\n" "use Illuminate\\Foundation\\Testing\\RefreshDatabase;\n" "use Illuminate\\Foundation\\Testing\\WithFaker;\n" @@ -248,5 +312,15 @@ Otherwise call FUNC with ARGS. This is meant as advice around (defun oni-php-in-static-call-context-p () (looking-back "::\\w+" (- (point) (line-beginning-position)))) +(defun oni-php-grep-symbol (symbol) + (interactive (list (thing-at-point 'symbol))) + (rgrep (rx (literal symbol)) + (map-elt grep-files-aliases "php") + (project-root (project-current)))) + +(define-key php-mode-map (kbd "C-c .") nil t) +(define-key php-mode-map (kbd "C-c . g") '("Search for symbol at point" . oni-php-grep-symbol)) +(define-key php-mode-map (kbd "C-c . a") '("Import symbol at point" . oni-php-add-use)) + (provide 'oni-php) ;;; oni-php.el ends here |
