Emacs Flymake and PHP Mode
This post covers the following sections from my init.
- PHP Mode
Emacs is old school. You're either new to it - which means you wouldn't be here unless it was your type of thing - or you know what you're looking for. In either case, search 'Emacs' in tags or search on this site. Then read the posts y date from oldest to newest.
In the last emacs post I covered lines 3129 - 3335. This post covers lines 3626 - 3796. The lines don't always match up because I take stuff out when I'm in the init, and the init is literal. The lines then cover also notes that are not tangled.
Flycheck is apparently better than flymake. Only I'm using emacs for web development, which includes a lot of work with frameworks (wordpress, hugo), so my linting needs are not that huge. You can check out my Flymake set-up as a starting point to
- start flymake with flymake-mode or flymake-start
- configure backends by installing from melpa and adding a hook in that modes use-package declaration
- if backend doesn’t work on a check, toggling flymake-mode will get flymake to try it again
- the following variables can be adjusted:
;(setq flymake-start-on-flymake-mode nil);, default is t ;set flymake severity to some number? (setq flymake-severity 7); ;set flymake check after change to buffer, default 0.5 seconds ;(setq flymake-no-changes-timeout 0.5) ;start flymake on newline (setq flymake-start-syntax-check-on-newline nil);, default is t ;custom flymake faces ;flymake-error, flymake-warning, flymake-note, flymake-error-bitmap, flymake-warning-bitmap, flymake-fringe-indicator-position, flymake-wrap-around ;flymake-warning
(use-package flymake-posframe :load-path flymake-posframe-p :custom (flymake-posframe-error-prefix "? ") :custom-face (flymake-posframe-foreground-face ((t (:foreground "white")))) :hook (flymake-mode . flymake-posframe-mode) );end flymake-posfram (use-package flymake-diagnostic-at-point ;:disabled :load-path flymake-diagnostic-p :after flymake :custom (flymake-diagnostic-at-point-timer-delay 0.1) (flymake-diagnostic-at-point-error-prefix "? ") (flymake-diagnostic-at-point-display-diagnostic-function 'flymake-diagnostic-at-point-display-popup) ;; or flymake-diagnostic-at-point-display-minibuffer :hook (flymake-mode . flymake-diagnostic-at-point-mode) );end flymake-diagnostics-at-point-mode (use-package flymake :commands (flymake-mode flymake-start) :config (setq flymake-severity 5) (define-key flymake-mode-map (kbd "M-n") 'flymake-goto-next-error) (define-key flymake-mode-map (kbd "M-p") 'flymake-goto-prev-error) ;test this ;(local-set-key [f4] 'flymake-display-err-menu-for-current-line) );end flymake mode
I use flymake diagnostic-at-point which isn't as I understand on Melpa. To use it paste the package into your package repo (commonly named elpa) and add the path to your load-path. Here's the source: flymake-diagnostic-at-point.
A Flymake Hook
I use the keys defined above, but you could also use a hook. This one doesn't invoke on temp buffers and sets a local key to jump to errors.
(add-hook 'python-mode-hook (lambda () (unless (eq buffer-file-name nil) (flymake-mode 1)) ;dont invoke flymake on temporary buffers for the interpreter (local-set-key [f2] 'flymake-goto-prev-error) (local-set-key [f3] 'flymake-goto-next-error) )) (require 'flymake-php) (add-hook 'php-mode-hook 'flymake-php-load)
I used PHP a lot in the past working on a custom php site. I've also used it to write some wordpress plugins and to work with a custom wordpress theme.
Like a lot of modes, php mode in emacs provides syntax highlighting, some indentation (coding style), syntax checking, completion, folding, some source referencing (jumping back through the stack to find where variables/symbols are defined) and snippet insertion.
The best way so far is just to use web-mode and add some customizations. I have a short-cuts for toggling between web-mode, html-mode (just different syntax highlighting), and php-mode.
Checking comes through flymake, completion through company-mode, with various backends added, folding through web-mode, and snippets through yasnippet.
;php-extras https://github.com/arnested/php-extras (use-package php-extras :commands (php-mode company-php) :config (require 'php-extras) );php-extras
;ac-php , as company backend (doesn't like so far windows) (use-package ac-php :after (auto-complete yasnippet company php-mode) :commands (php-mode company-php) :config (setq ac-php-php-executable "xampp-php-p") (ac-php-core-eldoc-setup) ;ac-source-php :hook (php-mode . ac-php-mode) );ac-php
;company-php ;php-auto-yasnippets, instructions type php function and M-x yas/create-php-snippet (use-package php-auto-yasnippets :load-path php-auto-yas-load-p :commands (yas/create-php-snippet) :config (require 'php-auto-yasnippets) ;set path as necessary (setq php-auto-yasnippet-php-program php-auto-yas-p) ) ;company mode (use-package company-php ;:after (company php-mode) :commands (php-mode company-php web-mode) :config ;ensure following functions works (could need a lambda) (defun my-company-php () (set (make-local-variable 'company-backends) '(( my-fetch-php-completions ;company-ac-php-backend php-extras-company ;ac-php company-dabbrev-code company-capf company-files )));end add to backends ) ;add completions from the net (otherwise file .ac-php-conf.json in project directory) (defun my-fetch-php-completions () (if (and (boundp 'my-php-symbol-list) my-php-symbol-list) my-php-symbol-list (message "Fetching completion list...") (with-current-buffer (url-retrieve-synchronously "http://www.php.net/manual/en/indexes.functions.php") (goto-char (point-min)) (message "Collecting function names...") (setq my-php-symbol-list nil) (while (re-search-forward "<a[^>]*class=\"index\"[^>]*>\\([^<]+\\)</a>" nil t) (push (match-string-no-properties 1) my-php-symbol-list)) my-php-symbol-list))) );end company-php
;php-mode (use-package php-mode :commands (php-mode web-mode yas/create-php-snippet ac-php-find-symbol-at-point ac-php-location-stack-back) ;:mode ("\\.php$" . web-mode) :config ;(require 'php-mode) (require 'company) (require 'company-php) (add-to-list 'load-path "c:/xampp/php/") (setq php-executable xampp-php-p) ;set the default coding style (indents, etc.) (setq php-enable-default-coding-style t) ;don't bother making html more friendly for php, use web-mode for files with php & html (setq php-mode-template-compatibility nil) ;(setq php-enable-wordpress-coding-style t) ;(setq php-enable-symfony2-coding-style t) (require 'flymake-php) (setq flymake-php-executable xampp-php-p) ;hooks (add-hook 'php-mode-hook '(lambda () ;; Enable company-mode (company-mode t) (company-php) (toggle-company-idle-delay) ;; Enable ElDoc support (optional) (ac-php-core-eldoc-setup) ;my-company-php is defined in company-php use-package declaration (my-company-php) (auto-fill-mode t) (rainbow-delimiters-mode t) (flymake-php-load) (company-fuzzy-mode) )) :bind (:map php-mode-map (("<f3>" . html-mode) ("<f4>" . web-mode) ("C-c C-s" . yas-insert-snippet)) ("C-c C-y" . yas/create-php-snippet) ("M-]" . ac-php-find-symbol-at-point) ("M-[" . ac-php-location-stack-back) ;("<f2>" . my-fetch-php-completions) );end bind );end use-package php-mode