複数のPhpStormのプロジェクトをMacのターミナルから開く

PhpStorm。多機能すぎて全然使いこなせてないけど、今日2017.1.2にアップデートした。(2016年12月でライセンス切れてた…)

複数のプロジェクトをターミナルから開けない

あんまり一度に複数のプロジェクトを開くことはないんだけど、以前は、プロジェクトのルートディレクトリで

phpstorm .

で複数開けてたんだけど、できなくなった。
もちろん、System Settings > Project Openingの設定は、Open project in new windowにしてある。

Tool > Create Command-line Launcher…で作り直した

これで直った。
phpstormで作ってたんだけど、今回は pstormで 😅
特に理由はないけど。
/usr/lobal/bin/xxxxx(決めた名前)にスクリプトが作られる。

中身はこれ↓↓

# open phpstorm from current directory
export PATH=$PATH:/usr/local/bin/pstorm

でsource ~/.bash_profileで無事複数開けるようになった 😀💡
場所は、/usr/local/bin/pstorm
中身は、

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import struct
import sys
import os
import time

# see com.intellij.idea.SocketLock for the server side of this interface

RUN_PATH = u'/Applications/PhpStorm.app'
CONFIG_PATH = u'/Users/oredayo/Library/Preferences/PhpStorm2017.1'
SYSTEM_PATH = u'/Users/oredayo/Library/Caches/PhpStorm2017.1'


def print_usage(cmd):
    print(('Usage:\n' +
           '  {0} -h | -? | --help\n' +
           '  {0} [project_dir]\n' +
           '  {0} [-l|--line line] [project_dir|--temp-project] file[:line]\n' +
           '  {0} diff <left> <right>\n' +
           '  {0} merge <local> <remote> [base] <merged>').format(cmd))


def process_args(argv):
    args = []

    skip_next = False
    for i, arg in enumerate(argv[1:]):
        if arg == '-h' or arg == '-?' or arg == '--help':
            print_usage(argv[0])
            exit(0)
        elif i == 0 and (arg == 'diff' or arg == 'merge' or arg == '--temp-project'):
            args.append(arg)
        elif arg == '-l' or arg == '--line':
            args.append(arg)
            skip_next = True
        elif skip_next:
            args.append(arg)
            skip_next = False
        else:
            path = arg
            if ':' in arg:
                file_path, line_number = arg.rsplit(':', 1)
                if line_number.isdigit():
                    args.append('-l')
                    args.append(line_number)
                    path = file_path
            args.append(os.path.abspath(path))

    return args


def try_activate_instance(args):
    port_path = os.path.join(CONFIG_PATH, 'port')
    token_path = os.path.join(SYSTEM_PATH, 'token')
    if not (os.path.exists(port_path) and os.path.exists(token_path)):
        return False

    with open(port_path) as pf:
        port = int(pf.read())
    with open(token_path) as tf:
        token = tf.read()

    s = socket.socket()
    s.settimeout(0.3)
    try:
        s.connect(('127.0.0.1', port))
    except (socket.error, IOError):
        return False

    found = False
    while True:
        try:
            path_len = struct.unpack('>h', s.recv(2))[0]
            path = s.recv(path_len)
            if os.path.abspath(path) == os.path.abspath(CONFIG_PATH):
                found = True
                break
        except (socket.error, IOError):
            return False

    if found:
        cmd = 'activate ' + token + '\0' + os.getcwd() + '\0' + '\0'.join(args)
        encoded = struct.pack('>h', len(cmd)) + cmd
        s.send(encoded)
        time.sleep(0.5)  # don't close the socket immediately
        return True

    return False


def start_new_instance(args):
    if sys.platform == 'darwin':
        if len(args) > 0:
            args.insert(0, '--args')
        os.execvp('open', ['-a', RUN_PATH] + args)
    else:
        bin_file = os.path.split(RUN_PATH)[1]
        os.execv(RUN_PATH, [bin_file] + args)


ide_args = process_args(sys.argv)
if not try_activate_instance(ide_args):
    start_new_instance(ide_args)

作り直す前がこれ↓↓

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import struct
import sys
import os
import time

# see com.intellij.idea.SocketLock for the server side of this interface

RUN_PATH = u'/Applications/PhpStorm.app'
CONFIG_PATH = u'/Users/oredayo/Library/Preferences/PhpStorm2016.3'
SYSTEM_PATH = u'/Users/oredayo/Library/Caches/PhpStorm2016.3'


def print_usage(cmd):
    print(('Usage:\n' +
           '  {0} -h | -? | --help\n' +
           '  {0} [-l|--line line] file[:line]\n' +
           '  {0} diff <left> <right>\n' +
           '  {0} merge <local> <remote> [base] <merged>').format(cmd))


def process_args(argv):
    args = []

    skip_next = False
    for i, arg in enumerate(argv[1:]):
        if arg == '-h' or arg == '-?' or arg == '--help':
            print_usage(argv[0])
            exit(0)
        elif arg == 'diff' and i == 0:
            args.append(arg)
        elif arg == 'merge' and i == 0:
            args.append(arg)
        elif arg == '-l' or arg == '--line':
            args.append(arg)
            skip_next = True
        elif skip_next:
            args.append(arg)
            skip_next = False
        else:
            if ':' in arg:
                file_path, line_number = arg.rsplit(':', 1)
                if line_number.isdigit():
                    args.append('-l')
                    args.append(line_number)
                    args.append(os.path.abspath(file_path))
                else:
                    args.append(os.path.abspath(arg))
            else:
                args.append(os.path.abspath(arg))

    return args


def try_activate_instance(args):
    port_path = os.path.join(CONFIG_PATH, 'port')
    token_path = os.path.join(SYSTEM_PATH, 'token')
    if not (os.path.exists(port_path) and os.path.exists(token_path)):
        return False

    with open(port_path) as pf, open(token_path) as tf:
        port = int(pf.read())
        token = tf.read()

    s = socket.socket()
    s.settimeout(0.3)
    try:
        s.connect(('127.0.0.1', port))
    except (socket.error, IOError):
        return False

    found = False
    while True:
        try:
            path_len = struct.unpack('>h', s.recv(2))[0]
            path = s.recv(path_len)
            if os.path.abspath(path) == os.path.abspath(CONFIG_PATH):
                found = True
                break
        except (socket.error, IOError):
            return False

    if found:
        cmd = 'activate ' + token + '\0' + os.getcwd() + '\0' + '\0'.join(args)
        encoded = struct.pack('>h', len(cmd)) + cmd
        s.send(encoded)
        time.sleep(0.5)  # don't close the socket immediately
        return True

    return False


def start_new_instance(args):
    if sys.platform == 'darwin':
        if len(args) > 0:
            args.insert(0, '--args')
        os.execvp('open', ['-a', RUN_PATH] + args)
    else:
        bin_file = os.path.split(RUN_PATH)[1]
        os.execv(RUN_PATH, [bin_file] + args)


ide_args = process_args(sys.argv)
if not try_activate_instance(ide_args):
    start_new_instance(ide_args)

【PhpStormメモ】

昨年の秋辺りからメインとして使い始めたPhpStorm。

より。
素のままでも大変便利なPhpStorm。言い換えると素のまましか知らない…(^0^;)

ブックマーク使ってみた

Navigate > Bookmarks

スクリーンショット 2016-01-17 13.57.38

これ。ファイルの任意の位置をブックマークして、シャッとジャンプできるやつです。
エディタを分割しててもなんだか使いづらくて、今まで使うのも面倒だからという理由で使っていなかったんですが、かなり便利ですね…もっと早く使えよって話です、ええ。。

ブックマークに番号(記号)振ってcontrol + 番号(記号)でも飛べるみたいですが、番号は覚えていられないかもなぁということで、Next Bookmark, Previous Bookmarkにショートカットを振って、ブックマークを行ったり来たりしてみることにしました。

これだけでも、相当便利ですね 🙂
(今まで使っていたCodaやSublime Textとかでも一切使ったことない前提です ^^;)

相当多機能なPhpStorm。使いこなすには時間かかりそうですが、先ずは便利だな!! と感じる機能からちょっとずつ使ってみたいと思います。

【メモ】PHPCS ( PHP_CodeSniffer ) + WordPress-Coding-Standards

codesniffer_wordpress

Macがぶっ飛んでから設定してなかったのでメモ。

PHP_CodeSnifferを使ってWordPressのプラグインやテーマがコーディングスタンダードに準拠しているかチェックする | Firegoby

PHP_CodeSniffer + WordPress-Coding-Standards をインストールする | deadwood

以前、宮さんの記事を参考に設定して、同じよーなエラー出て、修正できてたのに、今回また同じよーにエラー出たので、これやったらいかん…のにやっちまったので…(^0^;)

エラー

$ wpcs post-notifier.php 
ERROR: the "WordPress" coding standard is not installed. The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zend

“WordPress” coding standardないよ?あるのはMySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zendだけだよ?ってやつ。。

でも、ディレクトリにはちゃんとある。

codesniffer_wordpress
あるのに…

~/.composer/vendor/squizlabs/php_codesniffer/composer.jsonの中身を見てみると、

"autoload": {
  "classmap": [
    "CodeSniffer.php",
    "CodeSniffer/CLI.php",
    "CodeSniffer/Exception.php",
    "CodeSniffer/File.php",
    "CodeSniffer/Fixer.php",
    "CodeSniffer/Report.php",
    "CodeSniffer/Reporting.php",
    "CodeSniffer/Sniff.php",
    "CodeSniffer/Tokens.php",
    "CodeSniffer/Reports/",
    "CodeSniffer/Tokenizers/",
    "CodeSniffer/DocGenerators/",
    "CodeSniffer/Standards/AbstractPatternSniff.php",
    "CodeSniffer/Standards/AbstractScopeSniff.php",
    "CodeSniffer/Standards/AbstractVariableSniff.php",
    "CodeSniffer/Standards/IncorrectPatternException.php",
    "CodeSniffer/Standards/Generic/Sniffs/",
    "CodeSniffer/Standards/MySource/Sniffs/",
    "CodeSniffer/Standards/PEAR/Sniffs/",
    "CodeSniffer/Standards/PSR1/Sniffs/",
    "CodeSniffer/Standards/PSR2/Sniffs/",
    "CodeSniffer/Standards/Squiz/Sniffs/",
    "CodeSniffer/Standards/Zend/Sniffs/"
  ]
},

となってた。WordPress入ってない。
結局、Google先生に聞いて、前に参考にさせてもらった記事を発見。

PHP_CodeSniffer + WordPress-Coding-Standards をインストールする | deadwood

登録して、

$ phpcs --config-set installed_paths ~/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/WordPress

無事完了 🙂

$ phpcs -i
The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz, Zend, WordPress, WordPress-Core, WordPress-Docs, WordPress-Extra and WordPress-VIP

~/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer.conf 内に

&amp;lt;?php $phpCodeSnifferConfig = array ( 'installed_paths' =&amp;gt; '/Users/NAME/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/WordPress',
)
?&amp;gt;

ができてた。今からチェックスタートな所っす。

Using custom ruleset

If you need to further customize selection of sniffs for your project — you can create custom ruleset.xml standard. See provided project.ruleset.xml.example file and fully annotated example in PHP_CodeSniffer documentation.

WordPress-Coding-Standards/WordPress-Coding-Standards

っとruleset.xmlのサンプルもあるみたいなので、これも試してみた方がいいかもなぁ…(^0^;)

PhpstormだとWordPress-Coding-StandardsのCode Sniffer使えるんすね

PhpStormにWordPress-Coding-StandardsのCode Snifferを設定する。Mac編 – Qiita

~/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/WordPress/README.md

↑↑に

PhpStorm

Please see “PHP Code Sniffer with WordPress Coding Standards Integration” in PhpStorm documentation.

Sublime Text

Install the sublime-phpcs package, then use the “Switch coding standard” command in the Command Palette to switch between coding standards.

の記載がありました。
早速設定してみると、

スクリーンショット 2016-01-07 22.29.26

のようにハイライトしてくれます。
しかし、ターミナルからチェックした方が圧倒的に突っ込みが多いです。。

----------------------------------------------------------------------
FOUND 82 ERRORS AND 3 WARNINGS AFFECTING 62 LINES
----------------------------------------------------------------------
  11 | ERROR   | [ ] Missing @package tag in file comment
     |         |     (Squiz.Commenting.FileComment.MissingPackageTag)
  13 | ERROR   | [x] Space after opening control structure is
     |         |     required
     |         |     (WordPress.WhiteSpace.ControlStructureSpacing.NoSpaceAfterStructureOpen)
  13 | ERROR   | [x] Inline control structures are not allowed
     |         |     (Generic.ControlStructures.InlineControlStructure.NotAllowed)
  13 | ERROR   | [x] Expected 1 space after IF keyword; 0 found
     |         |     (Squiz.ControlStructures.ControlSignature.SpaceAfterKeyword)
  17 | ERROR   | [ ] Missing class doc comment
     |         |     (Squiz.Commenting.ClassComment.Missing)
  19 | ERROR   | [ ] Missing function doc comment
     |         |     (Squiz.Commenting.FunctionComment.Missing)

……まだまだ大量にあります…(*_*)
スペースやコメントとかスゲーチェック入るんすね。。あとコメントスタイルは、”/**”を使えよ?とも言われました。。

ふぅ…。一度やってしまえば多分後は楽なはず!!
後もう少しっすな 🙂

おわた

$ wpcs post-notifier.php 
Registering sniffs in the WordPress standard... DONE (81 sniffs registered)
Creating file list... DONE (1 files in queue)
Changing into directory /vccw/www/wordpress/wp-content/plugins/post-notifier
Processing post-notifier.php [PHP => 2552 tokens in 365 lines]... DONE in 183ms (0 errors, 0 warnings)
Time: 240ms; Memory: 8.75Mb

0になりました 🙂
パラメータの説明はピリオドで終われよ?とか、結構細かいチェック入りましたが、いい勉強になりました (^^)