diff options
Diffstat (limited to 'oni-php')
| -rw-r--r-- | oni-php/oni-php.el | 163 | ||||
| -rw-r--r-- | oni-php/snippets/php-mode/namespace | 6 |
2 files changed, 115 insertions, 54 deletions
diff --git a/oni-php/oni-php.el b/oni-php/oni-php.el index e5b50e4..1415d2b 100644 --- a/oni-php/oni-php.el +++ b/oni-php/oni-php.el @@ -4,7 +4,7 @@ ;; Author: Tom Willemse <tom@ryuslash.org> ;; Keywords: local -;; Version: 2026.0316.150229 +;; 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 @@ -30,7 +30,7 @@ (require 'align) (require 'company) (require 'hydra) -(require 'php-ts-mode) +(require 'map) (require 'project) (require 'whitespace) (require 'yasnippet) @@ -80,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 @@ -103,14 +103,26 @@ nil for some reason." (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))))) @@ -118,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." @@ -130,45 +146,79 @@ Do the insert N times." (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) -;; (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) -;; (apply func args))) +(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." + (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")) -;; (advice-add 'comment-dwim :around #'oni-php-comment-dwim) +(advice-add 'comment-dwim :around #'oni-php-comment-dwim) -(add-hook 'php-ts-mode-hook #'oni-php--set-require-final-newline) -(add-hook 'php-ts-mode-hook #'oni-php--whitespace-mode) -(add-hook 'php-ts-mode-hook 'company-mode) -(add-hook 'php-ts-mode-hook 'display-fill-column-indicator-mode) -(add-hook 'php-ts-mode-hook 'electric-indent-local-mode) -(add-hook 'php-ts-mode-hook 'fic-mode) -(add-hook 'php-ts-mode-hook 'flycheck-mode) -(add-hook 'php-ts-mode-hook 'ggtags-mode) -(add-hook 'php-ts-mode-hook 'oni-php--auto-fill-mode) -(add-hook 'php-ts-mode-hook 'oni-php-set-rainbow-identifier-faces) -(add-hook 'php-ts-mode-hook 'rainbow-delimiters-mode) -(add-hook 'php-ts-mode-hook 'rainbow-identifiers-mode) -(add-hook 'php-ts-mode-hook 'smartparens-mode) -(add-hook 'php-ts-mode-hook 'subword-mode) -(add-hook 'php-ts-mode-hook 'yas-minor-mode) +(add-hook 'php-mode-hook #'oni-php--set-require-final-newline) +(add-hook 'php-mode-hook #'oni-php--whitespace-mode) +(add-hook 'php-mode-hook 'company-mode) +(add-hook 'php-mode-hook 'display-fill-column-indicator-mode) +(add-hook 'php-mode-hook 'electric-indent-local-mode) +(add-hook 'php-mode-hook 'fic-mode) +(add-hook 'php-mode-hook 'flycheck-mode) +(add-hook 'php-mode-hook 'ggtags-mode) +(add-hook 'php-mode-hook 'oni-php--auto-fill-mode) +(add-hook 'php-mode-hook 'oni-php-set-rainbow-identifier-faces) +(add-hook 'php-mode-hook 'rainbow-delimiters-mode) +(add-hook 'php-mode-hook 'rainbow-identifiers-mode) +(add-hook 'php-mode-hook 'smartparens-mode) +(add-hook 'php-mode-hook 'subword-mode) +(add-hook 'php-mode-hook 'yas-minor-mode) (with-eval-after-load 'company (add-to-list 'company-backends 'company-ac-php-backend)) -(define-key php-ts-mode-map (kbd "C-c m") #'php-mode-hydra/body) -(define-key php-ts-mode-map (kbd ".") #'oni-php-insert-dot-dwim) +(define-key php-mode-map (kbd "C-c m") #'php-mode-hydra/body) +(define-key php-mode-map (kbd ".") #'oni-php-insert-dot-dwim) ;; In PHP code it's nice to have any ~=>~ aligned. @@ -183,7 +233,7 @@ Do the insert N times." `(php-array-arrow (regexp . ,(rx any (group (zero-or-more whitespace)) "=>" any)) (group . (1)) - (modes . '(php-mode web-mode php-ts-mode)) + (modes . '(php-mode web-mode php-mode)) (repeat . t))) ;; The WordPress coding standards specify that multiple assignments @@ -202,28 +252,40 @@ Do the insert N times." (modes . '(php-mode web-mode php-ts-mode)) (repeat . t))) -(with-eval-after-load 'php-ts-mode +(with-eval-after-load 'php-mode (with-eval-after-load 'yasnippet (oni-php-snippets-initialize))) ;;;###autoload -(add-to-list 'auto-mode-alist '("\\.inc\\'" . php-ts-mode)) +(add-to-list 'auto-mode-alist '("\\.inc\\'" . php-mode)) ;;;###autoload -(add-to-list 'auto-mode-alist '("\\.module\\'" . php-ts-mode)) +(add-to-list 'auto-mode-alist '("\\.module\\'" . php-mode)) ;;;###autoload (with-eval-after-load 'grep (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" @@ -250,12 +312,15 @@ Do the insert N times." (defun oni-php-in-static-call-context-p () (looking-back "::\\w+" (- (point) (line-beginning-position)))) -;;;###autoload -(when (and (functionp 'treesit-available-p) - (treesit-available-p) - (require 'treesit) - (treesit-ready-p 'php)) - (add-to-list 'major-mode-remap-alist '(php-mode . php-ts-mode))) +(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 diff --git a/oni-php/snippets/php-mode/namespace b/oni-php/snippets/php-mode/namespace index 01abd02..7a5b5e1 100644 --- a/oni-php/snippets/php-mode/namespace +++ b/oni-php/snippets/php-mode/namespace @@ -2,8 +2,4 @@ # name: namespace # key: ns # -- -namespace ${1:`(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))))) "/"))) - "\\")`};
\ No newline at end of file +namespace ${1:`(oni-php-generate-namespace)`};
\ No newline at end of file |
