Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

phpファイル保存時にLint処理(php -l)→コード整形→コーディング規約チェックをし、エラーがあればQuickFixに表示する

$
0
0

はじめに

phpファイルの保存時に

  • Lint処理(php -l)
  • コード整形
  • コーディング規約チェック

を行うvimプラグインを作ってみた。
(もうあるかもしれませんが勉強も兼ねて。。。)
Lint or コーディング規約チェックでエラーがあればQuickFixにその内容が表示されます。

ちなみにコード整形はphp-cs-fixerのvimプラグインを使用しています。
コーディング規約はphpcsを裏でたたいている感じです。
公開されているphpcsプラグインもあったのですが、QuickFixただ表示させているだけで、
:ccで飛べなかったので、自作しました。
(見つけられてないだけで、探せばちゃんとしたのがあるかもしれませんが。。。)

phpcsの見た目汚いですが一応:ccでとびます。ファイル名が表示されている番号をccで指定してください。
phpcs.png

事前準備

php-cs-fixerとphpcsを使うので、サーバーやVM等に落としておいてください。
一応リンク貼っておきます。Readmeの手順でやれば問題ないです。

php-cs-fixer
https://github.com/FriendsOfPHP/PHP-CS-Fixer

phpcs
https://github.com/squizlabs/PHP_CodeSniffer

phpcsはUbuntuには確かパッケージがあったと思うのでUbuntuの方はパッケージからインストールしてもよいと思います。ご自由にどうぞ。

あとは
php-cs-fixerのvim用のプラグインをインストールしておいてください
https://github.com/stephpy/vim-php-cs-fixer

コード

.vimrcでの設定とプラグインファイルのコードと2つ書きますが、
.vimrcにまとめて全部書いても動くのでご自由にどうぞ

.vimrc
" ---------------------------- php_cs_fixerプラグイン用の設定 ----------------------------
" @see https://github.com/FriendsOfPHP/PHP-CS-Fixer
" If php-cs-fixer is in $PATH, you don't need to define line below
let g:php_cs_fixer_path = "/usr/local/bin/php-cs-fixer" " define the path to the php-cs-fixer.phar
let g:php_cs_fixer_level = "psr2"             " which level ?
let g:php_cs_fixer_config = "default"         " configuration
"let g:php_cs_fixer_config_file = '.php_cs'   " configuration file
let g:php_cs_fixer_php_path = "php"           " Path to PHP
" If you want to define specific fixers:
let g:php_cs_fixer_fixers_list = "linefeed,short_tag,indentation"
let g:php_cs_fixer_enable_default_mapping = 1 " Enable the mapping by default (<leader>pcd)
let g:php_cs_fixer_dry_run = 0                " Call command with dry-run option
let g:php_cs_fixer_verbose = 0                " Return the output of command if 1, else an inline information.

" ---------------------------- php_cs用の設定 ----------------------------
let g:php_cs_fixer_use_flg = 1 " もし、php_cs_fixerプラグインを使いたくなければ0にしてください
let g:php_cs_use_flg = 1 " もし、php_csを使いたくなければ0にしてください
let g:php_cs_path = "/usr/bin/phpcs" " phpcsのパスを指定してください
let g:php_cs_standard = g:php_cs_fixer_level " PEARやPSR2等を指定してください

php-pack.vim

augroup PHP
    autocmd!
    " 書き込みのプレ処理
    autocmd! BufWritePre *.php call PHPPre()
    " 書き込みのポスト処理
    autocmd! BufWritePost *.php call PHPPost()

    " 書き込みのプレ処理
    function! PHPPre()
    endfunction

    " 書き込みのポスト処理
    " PHPLint
    " コードの整形
    function! PHPPost()
        " php -lの実行結果を変数に代入
        let l:php_lint_result = system('php -l '.bufname('%'))
        " No syntax errorsの文字列がmatchするかチェック
        let l:php_lint_err_check = matchstr(l:php_lint_result, 'No syntax errors')

        " エラーがあるときだけLintの結果を出力する
        if len(l:php_lint_err_check) == 0
            " 半角スペースごとに配列を分割
            let l:error_message_list = split(l:php_lint_result, ' ')
            let l:line_flg = 0
            let l:line_number = 0

            " エラーメッセージからエラーの行数を拾う
            " エラーメッセージのlineの後がエラーの行数みたい
            for word in l:error_message_list
                if l:line_flg == 1
                    let l:line_number = word
                    :break
                else
                    if word == 'line'
                        let l:line_flg = 1
                    endif
                endif
            endfor

            " QuickFixのリストの末尾にエラーの内容を追加する
            let l:qflist = []
            call add(l:qflist, {'filename': bufname('%'), 'type': 'i', 'lnum': l:line_number, 'col': 1, 'text': l:php_lint_result})
            call setqflist(l:qflist)
            " QuickFixを表示
            :copen
        else
            " QuickFixを閉じる
            :cclose
            " php_cs_fixerを利用してコードを整形
            if g:php_cs_fixer_use_flg == 1
                call PhpCsFixer()
            endif
            " phpcsでコードチェック
            if g:php_cs_use_flg == 1
                call PhpCs()
            endif
        endif
    endfunction

    " php_cs_fixerの設定
    function! PhpCsFixer()
        " @see https://github.com/FriendsOfPHP/PHP-CS-Fixer
        :call PhpCsFixerFixFile()
        syntax on
    endfunction

    " php_csの設定
    function! PhpCs()
        " パスが通っているか確認のため確認用のphpcsコマンドをたたく
        let l:check_phpcs = system(g:php_cs_path.' -i 1>/dev/null 2> /dev/null && echo $?')

        " phpcsのパスが通っている場合はphpcsでチェック
        if l:check_phpcs == 0
            set errorformat+=\"%f\"\\,%l\\,%c\\,%t%*[a-zA-Z]\\,\"%m\"\\,%*[a-zA-Z0-9_.-\\,]

            " phpcsコマンドをたたく
            let l:phpcs_result = system(g:php_cs_path.' --standard='.g:php_cs_standard.' '.bufname('%'))

            " phpcsチェックerrorの場合
            if l:phpcs_result != ''
                let l:i = 0
                let l:qflist = []
                " phpcsのエラーメッセージを改行ごとにsplit
                let l:error_message_list = split(l:phpcs_result, "\n")

                for message in l:error_message_list
                    " エラー内容を表すメッセージは | 行番号 | ERROR or Warning | 内容
                    " のフォーマットなので、|のある行を探す
                    let l:match_result = matchstr(message, '|')
                    if len(l:match_result) > 0
                        " split_message[0] 行番号
                        " split_message[1] ERROR or Warning
                        " split_message[2] 内容
                        let l:split_message = split(message, '|')

                        " split_message[0]には半角スペースが含まれるのでtrim
                        if len(substitute(l:split_message[0], " ","","g")) > 0
                            call add(l:qflist, {'filename': bufname('%'), 'text': l:split_message[1].l:split_message[2], 'lnum':substitute(l:split_message[0], " ","","g"), 'col': 1})
                        else
                            call add(l:qflist, {'filename': "", 'text': l:split_message[2], 'lnum':'', 'col': 1})
                        endif
                    endif
                endfor

                " QuickFixのリストの末尾にエラーの内容を追加する
                call setqflist(l:qflist)
                " QuickFix open
                copen
            else
                " QuickFix close
                cclose
            endif

        " phpcsのパスが通っていない場合はerror表示
        else
            echo 'Error! phpcs not found.'
        endif

    endfunction
augroup END

おわりに

一応g:php_cs_fixer_use_flgやg:php_cs_use_flg値で処理を通過させるさせないを制御できるようにしておきました。
簡単ですが以上です。
もしお役に立てれば幸いです。


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>