keicy/.emacs.d

phpのリンターを入れる

Closed this issue · 4 comments

keicy commented

OS側モジュールインストール

FlycheckのドキュメントよりOS側への依存は3点

これらについて

  • php は phpenv(※anyenv経由)でインストール済
  • phpmd はapt で入る
  • phpcs は、PHPのライブラリマネージャである pear 経由で入れる
    • pear は apt で入る

よってまず下記を実施

sudo apt-get install phpmd php-pear

その後下記を実施

sudo pear install PHP_CodeSniffer
keicy commented

Flycheck設定

FlycheckにPHP用の設定は用意されているが、これは web-mode では動かない..( php-mode では動く。が、試した感じ、このモードはHTML部分のインデント制御や補完に難アリで使えなかった..)
この用意された設定を web-mode で機能させるため、Flycheckの該当部分のコードを設定ファイルで上書き再定義する必要がある。
具体的には、対象モードに web-mode を追記したものを再定義する。詳細は下記コードのコメント参照。なお、元のコードは flycheck/flycheck.el に定義されている。

; OVERRIDE Flycheck's elisp source codes @flycheck/flycheck.el.
  ; r.f. ) https://truongtx.me/2014/07/22/setup-php-development-environment-in-emacs 
(with-eval-after-load-feature 'flycheck ; この行なしではエラーになるため注意!
  (flycheck-define-checker php
    "A PHP syntax checker using the PHP command line interpreter.

  See URL `http://php.net/manual/en/features.commandline.php'."
    :command ("php" "-l" "-d" "error_reporting=E_ALL" "-d" "display_errors=1"
              "-d" "log_errors=0" source)
    :error-patterns
    ((error line-start (or "Parse" "Fatal" "syntax") " error" (any ":" ",") " "
            (message) " in " (file-name) " on line " line line-end))
    :modes (php-mode php+-mode web-mode) ; ここに追加している
    :next-checkers ((warning . php-phpmd)
                    (warning . php-phpcs)))

  (flycheck-define-checker php-phpmd
    "A PHP style checker using PHP Mess Detector.

  See URL `https://phpmd.org/'."
    :command ("phpmd" source "xml"
              (eval (flycheck-option-comma-separated-list
                     flycheck-phpmd-rulesets)))
    :error-parser flycheck-parse-phpmd
    :modes (php-mode php+-mode web-mode) ; ここに追加している
    :next-checkers (php-phpcs))

  (flycheck-define-checker php-phpcs
    "A PHP style checker using PHP Code Sniffer.

  Needs PHP Code Sniffer 2.6 or newer.

  See URL `http://pear.php.net/package/PHP_CodeSniffer/'."
    :command ("phpcs" "--report=checkstyle"
              ;; Use -q flag to force quiet mode
              ;; Quiet mode prevents errors from extra output when phpcs has
              ;; been configured with show_progress enabled
              "-q"
              (option "--standard=" flycheck-phpcs-standard concat)
              ;; Pass original file name to phpcs.  We need to concat explicitly
              ;; here, because phpcs really insists to get option and argument as
              ;; a single command line argument :|
              (eval (when (buffer-file-name)
                      (concat "--stdin-path=" (buffer-file-name)))))
    :standard-input t
    :error-parser flycheck-parse-checkstyle
    :error-filter
    (lambda (errors)
      (flycheck-sanitize-errors
       (flycheck-remove-error-file-names "STDIN" errors)))
    :modes (php-mode php+-mode web-mode) ; ここに追加している
    ;; phpcs seems to choke on empty standard input, hence skip phpcs if the
    ;; buffer is empty, see https://github.com/flycheck/flycheck/issues/907
    :predicate (lambda () (not (flycheck-buffer-empty-p))))
)
keicy commented

補足

web-mode は複数のタイプのファイル(php,js,etc)で使うため、メジャーモードに依るチェッカー選択ではダメで、ファイル拡張子に依るチェッカー選択という挙動が必要。

これは、 auto-mode-alist に追加するデータの第2引数に独自定義関数を渡すことで実現する。

(add-to-list 'auto-mode-alist '("\\.php?\\'" . my-php-mode-hook))

(defun my-php-mode-hook ()
  (setq web-mode-markup-indent-offset 2)
  (setq web-mode-css-indent-offset 2)
  (setq web-mode-code-indent-offset 4)
  (web-mode)
  (flycheck-mode)
)

ちなみに、いつもの第2引数 (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))web-mode も実は「モード名」ではなくてモードを有効化する関数(mode-name-function)である。

keicy commented

#97 によりクローズ