diff --git a/php-mode.el b/php-mode.el index 1e232db2..d50b6b2d 100644 --- a/php-mode.el +++ b/php-mode.el @@ -342,6 +342,12 @@ In that case set to `NIL'." :tag "PHP Mode Disable C Mode Hook" :type 'boolean) +(defcustom php-mode-enable-project-local-variable t + "When set to `T', apply project local variable to buffer local variable." + :group 'php-mode + :tag "PHP Mode Enable Project Local Variable" + :type 'boolean) + (defun php-mode-version () "Display string describing the version of PHP Mode." (interactive) @@ -1116,6 +1122,11 @@ After setting the stylevars run hooks according to STYLENAME (php-set-style (symbol-name coding-style))) (remove-hook 'hack-local-variables-hook #'php-mode-set-style-delay))))) +(defun php-mode-set-local-variable-delay () + "Set local variable from php-project." + (php-project-apply-local-variables) + (remove-hook 'hack-local-variables-hook #'php-mode-set-local-variable-delay)) + (defvar php-mode-syntax-table (let ((table (make-syntax-table))) (c-populate-syntax-table table) @@ -1169,6 +1180,9 @@ After setting the stylevars run hooks according to STYLENAME ;; PHP vars are case-sensitive (setq case-fold-search t) + (when php-mode-enable-project-local-variable + (add-hook 'hack-local-variables-hook #'php-mode-set-local-variable-delay t t)) + ;; When php-mode-enable-project-coding-style is set, it is delayed by hook. ;; Since it depends on the timing at which the file local variable is set. ;; File local variables are set after initialization of major mode except `run-hook' is complete. diff --git a/php-project.el b/php-project.el index 827be72d..18115cc0 100644 --- a/php-project.el +++ b/php-project.el @@ -72,6 +72,19 @@ ;; Constants (defconst php-project-composer-autoloader "vendor/autoload.php") +;; Custom variables +(defgroup php-project nil + "Major mode for editing PHP code." + :tag "PHP Project" + :prefix "php-project-" + :group 'php) + +(defcustom php-project-auto-detect-etags-file nil + "If `T', automatically detect etags file when file is opened." + :tag "PHP Project Auto Detect Etags File" + :group 'php-project + :type 'boolean) + ;; Variables (defvar php-project-available-root-files '((projectile ".projectile") @@ -104,6 +117,12 @@ STRING (put 'php-project-root 'safe-local-variable #'(lambda (v) (or (stringp v) (assq v php-project-available-root-files)))) + (defvar-local php-project-etags-file nil) + (put 'php-project-etags-file 'safe-local-variable + #'(lambda (v) (or (functionp v) + (eq v t) + (php-project--eval-bootstrap-scripts v)))) + (defvar-local php-project-bootstrap-scripts nil "List of path to bootstrap php script file. @@ -172,7 +191,6 @@ Typically it is `pear', `drupal', `wordpress', `symfony2' and `psr2'.") (put 'php-project-server-start 'safe-local-variable #'(lambda (v) (or (functionp v) (php-project--eval-bootstrap-scripts v))))) - ;; Functions (defun php-project--validate-php-file-as-template (val) @@ -229,6 +247,17 @@ Typically it is `pear', `drupal', `wordpress', `symfony2' and `psr2'.") (t (prog1 nil (warn "php-project-php-file-as-template is unexpected format"))))) +(defun php-project-apply-local-variables () + "Apply php-project variables to local variables." + (when (null tags-file-name) + (when (or (and php-project-auto-detect-etags-file + (null php-project-etags-file)) + (eq php-project-etags-file t)) + (let ((tags-file (expand-file-name "TAGS" (php-project-get-root-dir)))) + (when (file-exists-p tags-file) + (setq-local php-project-etags-file tags-file)))) + (when php-project-etags-file + (setq-local tags-file-name (php-project--eval-bootstrap-scripts php-project-etags-file))))) ;;;###autoload (defun php-project-get-bootstrap-scripts () "Return list of bootstrap script."