Visual Studio Code の PHP 言語サポート vscode-php-intellisense

本記事の 2017 年版を記載しましたのでご参照ください。

https://another.maple4ever.net/archives/2321/


Visual Studio Code Advent Calendar 2016 の 12日目です!

ここのところずっとウォッチしていました、Visual Studio Code(vscode)で利用可能な PHP サポート拡張になります “vscode-php-intellisense” が完成度をあげ、かなり良い感じになっています。 🙂

https://github.com/felixfbecker/vscode-php-intellisense

Advanced PHP IntelliSense for Visual Studio Code. In opposite to the included PHP IntelliSense and other PHP extensions, this uses an AST to parse the source code instead of relying on naive regular expression parsing.

少し前まで PHP をかくときは、Eclipse の PHP Developer Tools を使っていましたが、vscode-php-intellisense がほぼ同様の機能を実装しましたので、検証しながら乗り換えをしております。

以下、vscode-php-intellisense で WordPress を読ませて動作させている様子です。(サイトの横幅の関係でスクリーンキャストがつぶれてしまいましたので、見づらい場合は画像をクリックしてフルサイズでご覧ください)

まずはエラーチェック。構文間違えなどをリアルタイムに指摘してくれます。

error

定義ジャンプ。PHPDoc が表示でき、関数・メソッドの定義位置に F12 でジャンプします。これがないと困ります 🙂

jump

「定義をここに表示」と「参照先検索」機能。「ここに表示」はインラインで関数定義の内容をぱらっとみるとき便利です。また、PHP は動的型付け言語なので完全ではありませんが、呼び出し元検索があるのは嬉しい部分です。

ref

最後は入力補完。 PHP の標準関数を補完しています。 PHPDoc を表示しながら、引数が入力できます。

comp

ユーザ定義関数の補完も現在 master ブランチでは可能になっています。 コメントアノテーションもみて、参照を解決しているのが分かります。

https://github.com/felixfbecker/php-language-server/pull/165

comp2

Ecipse PDT や PHPStorm 並の機能です。すごい。

このペースでいきますと、おそらく年内にはユーザ定義関数の補完も実装が完了し使える形になると思います。つまりは、WordPress や baserCMS のテンプレートタグの補完が可能になります。 😀

ユーザ定義関数補完以外は既に動作するものが Marketplase にリリースされていますので、まずは導入してアップデートを楽しみに待ちましょう。 🙂

https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense

Advanced PHP IntelliSense for Visual Studio Code.
In opposite to the included PHP IntelliSense and other PHP extensions, this uses an AST to parse the source code
instead of relying on naive regular expression parsing.

その他の機能のスクリーンキャストは以下で見ることができます。(ぼくのへたなアニメよりずっと分かりやすいのでぜひご覧ください…)

https://github.com/felixfbecker/vscode-php-intellisense

さて、この拡張は同じ作者の方がかかれている PHP 7 で実装された php-language-server を利用して動作しています。(このため、拡張を動作させるには vscode を動かすマシンに PHP 7 が導入され、パスが通っている必要があります)

この親となっている php-language-server ですが、これは Microsoft Language Server Protocol の実装です。

Language Server Protocol は、エディタ(IDE)と言語解析器をつなぐための共通プロトコルですので、今後 php-language-server は vscode 以外のテキストエディタと接続できる可能性があります。 (既に Eclipse Che が PHP サポートの実装に php-language-server を使っています)

逆に Visual Studio Code から見た場合、新しく追加された言語サーバーに接続することで、どんどん対応言語を増やすことができる仕組みです。(現在 vscode は Language Server Protocol クライアントのリファレンス実装のような形になっています)

vscode と Language Server Protocol を使って対応されている言語の一覧は以下で見ることができます。

https://github.com/Microsoft/language-server-protocol/wiki/Protocol-Implementations

Language Maintainer Repository
PowerShell MS VS Code PowerShell extension
C++ MS VS Code C++ extension
C# OmniSharp Many integrations, repository
JSON MS Bundled with VS Code
CSS/LESS/SASS MS Bundled with VS Code
Xtext language framework Eclipse Eclipse Xtext
Crane PHP HvyIndustries VS Code Extension
PHP Felix Becker php-language-server
Haxe Dan Korostelev (@nadako) VS Code Haxe extension
Java (javac) @georgewfraser Javac based Java support
RAML RAML Workgroup raml-language-server Work in Progress
API Elements Vincenzo Chianese(@XVincentX) vscode-apielements
groovy Palantir groovy-language-server
Java (Eclipse) Eclipse, RedHat java-language-server, becoming Eclipse JDTLS
OCaml/Reason freebroccolo ocaml-language-server
Go Sourcegraph sourcegraph-go
Rust Jonathan Turner rustls
Scala Iulian Dragos dragos-vscode-scala
Polymer Polymer Team polymer-editor-service

まだまだ未完成のものもありますが、PowerShell などは完成形になっていてかなり使いやすいです。 標準の PowerShell ISE より良いかも?

というわけで、このような言語サポートも手伝って Visual Studio Code は愛用のエディタになりました。開発も活発なので今後も楽しみです。 😀

OSC 北海道 2016 baserCMS & WordPress セミナー・ブース出展

2016/6/18(土)に開催されました「OSC 北海道 2016(2日目)」で、WordPress & baserCMS セミナー・ブース出展を行いました。

お越しになってくださいった方、本当にありがとうございました!

baserCMS セミナー & ブース出展

baserCMS セミナーでは「コーポレートサイトにちょうどいい、国産 CMS 「baserCMS」の紹介」ということで、baserCMS の紹介をさせていただきました。

baserCMS 4.0 開発系のデモも江頭さんのご協力のもとすることができ、興味を持っていただいた方も多かったと思います。

セミナー直前にデモサイトが壊れるという、びっくりアクシデントがありましたが、セミナー中に江頭さんがなんとかしてくれ、最後は江頭さんによる詳細な解説もしていただきました。 ありがとうございました!

ブースにて江頭さん。WP のタトゥーとは 🙂

13467683_1167016726683780_360936745_o

福岡より、上田さん、はまちさんも来ていただき、ブースも盛況でした。 楽しかったです、ありがとうございました!

WordPress セミナー & ブース出展

WordBench セミナーでは「REST API を活用した、新しい WordPress サイト製作手法」を解説しました。

最近、REST を使ったサイトも増えてきていますので、活用していただければと思ってスライドをつくりました。

ひろましゃ

ひろましゃ

baserCMS と SaCSS(sapporo.css) の真ん中ブースでした。(写真右、コモモ氏による、お手製べっしーにも注目ですw

13487363_1167016833350436_1735057596_n

大懇親会

終了後の大懇親会にて SaCSS ハムさんとぱちり。 セミナー2本やりましたゆえ、疲労が色濃くでております(笑

13480142_1167016536683799_2104078938_n

ということで、OSC 北海道スタッフ、関係者のみなさまお疲れ様でした! 重ねまして来てくださった方、お話させていただいたかたありがとうございました。

今後ともよろしくお願いいたします!

Grooscript で Canvas アニメーション

G* Advent Calendar 2015 16日目です!(更新前に来てくださった方すいません…)


Groovy を altJS にしてしまった驚異の Grooscript を紹介したいと思います。Groovy をかくとソースコードが JavaScript に変換され、ブラウザや node.js 上で実行できてしまいます。

論よりrunということで、Try online がありますので試してみると良いと思います。

Try groovy to javascript conversion with grooscript

http://grooscript.org/conversions.html

ここでは、ブラウザを Grooscript の実行環境とし、Groovy で Canvas を使ったアニメーションのプログラミングをしてみます。

Grooscript を始めるには Grooscript の Gradle plugin を使うと簡単です。初期コードの作成からファイルウォッチからの変換まで可能です。

build.gradle

plugins {
    id "org.grooscript.conversion" version "1.2.2"
}

これで、

gradle initStaticWeb

とすれば、初期コードを生成してくれます。

grooscript-01

この状態で次のようにすれば、src/main/groovy 配下の *.groovy ファイルの更新を監視して、src/main/webapp/js/app の下に変換した *.js を入れてくれます。

gradle --daemon convertThread

監視を止める場合は gradle のデーモンを停止させればOKです。(Windows, Linux, OS X とも動作するはずです)

gradle --stop

あとは Groovy をかけば完成です。 🙂

ここでは Canvas アニメーションを実装するために、src/main/webapp/index.html を次のようにしました。

<html>
<head>
<title>groovy on browser!</title>
<link rel=&quot;stylesheet&quot; href=&quot;css/style.css&quot; />
<script type=&quot;text/javascript&quot; src=&quot;js/lib/grooscript.min.js&quot;></script>
<script type=&quot;text/javascript&quot; src=&quot;js/app/Presenter.js&quot;></script>
<meta name=&quot;viewport&quot; content=&quot;width=device-width&quot; />
<meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;>
</head>
<body>
<canvas></canvas>
</body>

src/main/groovy/Presenter.groovy で Canvas に対するアニメーション処理を Groovy でかきました。

ブラウザの window や document などのオブジェクトはそのまま記述できます。

import org.grooscript.asts.GsNative

class Animation {

    static ANIMATION_FPS = 60;

    def canvas
    def context
    def width
    def height

    def actor
    def line

    Animation() {
        window.addEventListener('load', init, false)
        window.addEventListener('resize', init, false)
        window.addEventListener('orientationchange', init, false)
        window.setInterval(update, 1000 / ANIMATION_FPS, false)
        render()
    }

    def init() {
        actor = []
        canvas = document.getElementsByTagName('canvas')[0]
        context = canvas.getContext('2d')
        width = canvas.clientWidth
        height = canvas.clientHeight
        canvas.setAttribute("width" ,width);
        canvas.setAttribute("height" ,height);
        for(def degree = 0 ; degree <= 360; degree += 360/86) {
            this.actor << new Ham("images/ham.png"
                , this.width
                , this.height
                , degree
            )
        }
    }

    def update() {
        actor.each {
            it.update()
        }
    }

    def render() {
        window.requestAnimationFrame(render)
        if(!context) return
        context.fillStyle = "#000"
        context.fillRect(0, 0, width, height)
        actor.each {
            it.draw(context)
        }
    }
}

class Ham extends Actor {

    def swidth
    def sheight
    def degree
    def sx
    def sy
    def sv

    Ham(def url, def w, def h, def d) {
        super(url)
        swidth = w
        sheight = h
        sx = swidth / 2
        sy = sheight / 2
        sv = 1
        degree = d
        width = 48
        height = 48
    }

    @GsNative
    def update() {/*
        var radian = Math.PI / 180 * this.degree
        this.x = Math.cos(radian) * (this.sx / 2 - 24) + this.swidth / 2 - 24
        this.y = Math.sin(radian) * (this.sy / 2 - 24) + this.sheight / 2 - 24
        this.degree += 0.9
        if(this.degree > 360) {
            this.degree = 0
        }
        this.sx += this.sv * 8
        this.sy += this.sv * 8
        if(this.sx >= this.swidth
            || this.sy >= this.sheight
            || this.sx <= (this.swidth * -1) + 48 + 24
            || this.sy <= (this.sheight * -1) + 48 + 24
            ) {
            this.sv = this.sv * -1
        }
        this.width = 48 + (this.sx / 48)
        this.height = 48 + (this.sy / 48)
    */}
}

abstract class Actor {

    def image
    def x = 0
    def y = 0
    def width
    def height

    Actor(def url) {
        image = Resource.getInstance().getImage(url)
    }

    abstract update()

    @GsNative
    def draw(context) {/*
        if(!this.image['loaded']) return
        context.drawImage(this.image['image'], this.x, this.y, this.width, this.height)
    */}
}

class Resource {

    def static resource = new Resource()
    def images = [:]

    private Resource() { }
    
    def static getInstance() {
        return resource
    }

    def getImage(url) {
        if(!images.containsKey(url)) {
            images[url] = [:]
            def image = document.createElement('img')
            image.src = url
            image.addEventListener('load', {
                images[url]['image'] = image
                images[url]['loaded'] = true
                images[url]['width'] = image.naturalWidth
                images[url]['height'] = image.naturalHeight
            }, false)
        }
        return images[url]
    }
}

new Animation()

本当に Groovy です。 😀

一部 @GsNative というアノテーションがついたコメント実装されているメソッドは JavaScript のネイティブコードです。 速度を稼ぎたい部分は、このように(Groovy で変換された周りのコードを考えつつ) JS をそのままかくこともできます。

以下をクリックすると、実際に動いている様子が見ることができます。

ham

変換された JavaScript のコードを見ると面白いと思います。

Grooscript はここ1年で node.js、require.js や React.js の対応が進むなど、開発を見ているのも楽しいです。

ブラウザとのつなぎも簡単ですので、Groovy な方はぜひ試してみてください 🙂

Keep on Groovy-ing!