kick the base

好きな映画、音楽、マンガ、プログラム、デザイン、3DCG、ゲームのこと。

Houdini: VEXをカスタマイズしたVS Codeで書く02

皆さんVEX書いてますか?ぼくはだいぶ慣れてきました。 今回はVEXを外部エディタのVS Codeで書くための設定についてお話します。

Houdini x VS Codeについての記事は過去にHoudini: VEXをカスタマイズしたVS Codeで書くVim風VS Codeカスタマイズ詳細というものを書いたことがあるのですが、使用しているプラグインやスニペットが変わってきたのでその備忘録を兼ねての紹介になります。

「Houdiniにはテキストエディタが内蔵されてるんだから、それを使えばいいんじゃない?」というご意見はごもっともなのですが、VS Codeを選択するメリットもあります。

  1. ローカル変数の補完も可能
  2. 優秀なコード補完、自由なスニペットにより打鍵が大きく減る
  3. Functions descriptions(関数の説明)が表示されるため引数の入力ミスが減る
  4. 関数を調べる際、Houdini付属のヘルプは起動速度が遅く、Webヘルプを繋ぐと起動は速いが検索窓の絞り込み検索が効かない

これらがメリットかなと思っています。もちろんデフォルトのエディタにもいいところがあるので、

  • すでに使用方法を理解しており脳から湧き出てくるコードを書くときは付属のエディタで
  • サポートが欲しい複雑なコードを書く、もしくは使用頻度・理解度の少ない関数を利用するケースはVS Codeを利用する

という感じで併用するといいんじゃないかなと思います。

使用感のご紹介

以下にずっと設定の説明が続くので、まずは操作しているところをご紹介して、いいなと思ったら導入していただくといいかと思います。

ローカル変数の補完

長いローカル変数も楽々補完。これにより適正な変数名を付けることが可能に。

f:id:kickbase:20190211210837g:plain

独自スニペットの利用

タブストップ(スニペット展開後にカーソルが移動するやつ)が便利ですね。rand関数展開時にカッコの中にカーソルが移動しているのがわかるかと思います。

f:id:kickbase:20190211211011g:plain

@opinputN_attrib@OpInputNなど、入力番号の数え方が異なるシンタックスなどは自前のスニペットに注意点を書いておくとよいでしょう。

f:id:kickbase:20190211211120g:plain

関数の説明が便利

引数の順番や内容が事前にわかるので間違いが少なくなります。特に新しい関数を試すときなどは役に立ちます。

f:id:kickbase:20190211211823g:plain

執筆時の環境

  • Windows10 Pro
  • Houdini 17.0.416
  • VS Code 1.31.0

外部エディタを登録する

$HOUDINI_USER_PREF_DIRにあるhoudini.envを直接編集してもよいですが、GUIから指定できるため環境設定ファイルを直でいじるのが不安な方はこちらでいきましょう。OS関係なくよしなにやってくれます。

メインメニュー > Edit > Hotkeys > Set External Expression Editorを押すとダイアログが出るので、VS Codeを選択しましょう。

f:id:kickbase:20190211213141j:plain

外部エディタを呼び出しやすくするためのプラグインを入れる

Houdini Expression Editorというものを使用しています*1テンプファイルをWatchして保存と同時にコードが転送されるのがよいところで、今のところ安定して動いています。

本ツールはドネーションウェアなので、気に入ったら作者に寄付をしてもよいでしょう。

あとはExternal Expression Editorにショートカットを割り当てるだけです。ぼくはalt+Eに割り当てました。

(注意) 多分Hotkeyの不具合で下記症状が確認されてます。

  1. VExpressionからコンテキストメニューを呼び出し
  2. Expression > External Expression Editorを表示しないとホットキーが起動しない

f:id:kickbase:20190211213157j:plain

こちらサポートに質問しようかなと思ってます。

参考サイト

Editor/External Editor hotkey not working

VS Codeの設定

機能拡張の導入

基本的にVEXを書くためだけの設定です。(外部エディタでHoudini Pythonを書くこともできますが、今のところhouモジュールの補完が効かないので設定ができたらPython周りの設定をしてまた記事に書きます)

重要な機能拡張は基本ひとつです。

f:id:kickbase:20190211213344j:plain

VEX

これがないと始まらないですね。

VEX

その他はお好きなように入れていただければと思いますが、Setting Syncは便利だったので追記しておきます。

Setting Sync

スニペット、キーバインディング、基本設定を複数のマシンで同期する機能拡張です。ドネーションウェアなので気に入ったら寄付をどうぞ。

Gistを利用するのでGithub IDが必要になりますが、パパっとコードをシェアするのにGistは非常に優秀なのと、最近プライベートリポジトリも個人開発レベルでは無料になったので開発環境(dotfiles)の管理などにも便利なのでオススメです。

PythonエディタとしてのVS Code

下記URLにhouモジュールの補完方法が紹介されてたのですが、うまくいかなかったので落ち着いたら再トライしてみます。

HOUDINI TIP | USING HOU MODULE IN VISUAL STUDIO CODE

基本設定

全設定を載せておきます。ほとんどがVimキーバインドの設定なので説明は割愛します。

f:id:kickbase:20190211213411j:plain

f:id:kickbase:20190211213423j:plain

setting.json

{
    "window.zoomLevel": 1,
    "editor.fontFamily": "Ricty Diminished",
    "editor.fontSize": 20,
    "git.ignoreMissingGitWarning": true,
    "editor.formatOnSave": true,
    "editor.formatOnType": true,
    "vim.hlsearch": true,
    "vim.searchHighlightColor": "rgba(255, 235, 60, 0.4)",
    "vim.easymotion": true,
    "vim.easymotionKeys": "sdfghjkl",
    "vim.sneak": true,
    "vim.incsearch": true,
    "vim.useSystemClipboard": true,
    "vim.leader": "<space>",
    "vim.visualstar": true,
    "vim.handleKeys": {
        "<C-a>": false,
        "<C-f>": false
    },
    "vim.normalModeKeyBindingsNonRecursive": [{
            "before": [
                "Z",
                "Z"
            ],
            "commands": [
                ":wq"
            ]
        },
        {
            "before": [
                "<C-c>"
            ],
            "commands": [
                ":nohl",
            ]
        },
        {
            "before": [
                "+"
            ],
            "after": [
                "<C-a>"
            ]
        },
        {
            "before": [
                "-"
            ],
            "after": [
                "<C-x>"
            ]
        },
        {
            "before": [
                ";"
            ],
            "after": [
                ":"
            ]
        },
        {
            "before": [
                ":"
            ],
            "after": [
                ";"
            ]
        }
    ],
    "sync.gist": "*****************************"
}

スニペットの登録

ここらへんはお好みになりますが、よく使うアトリビュートや、機能拡張ではカバーできない関数などをスニペットにしています。*2

f:id:kickbase:20190211213539j:plain

f:id:kickbase:20190211213555j:plain

vex.json

{
    "int": {
        "prefix": "int",
        "body": [
            "int "
        ],
        "description": "int"
    },
    "float": {
        "prefix": "flo",
        "body": [
            "float "
        ],
        "description": "float"
    },
    "string": {
        "prefix": "str",
        "body": [
            "string "
        ],
        "description": "string"
    },
    "vector": {
        "prefix": "vec",
        "body": [
            "vector"
        ],
        "description": "vector"
    },
    "matrix": {
        "prefix": "mat",
        "body": [
            "matrix"
        ],
        "description": "vector"
    },
    "array": {
        "prefix": "arr",
        "body": [
            "${1:type}[]$0"
        ],
        "description": "array"
    },
    "@ptnum": {
        "prefix": "ptn",
        "body": [
            "@ptnum"
        ],
        "description": "ptnum"
    },
    "@numpt": {
        "prefix": "npt",
        "body": [
            "@numpt"
        ],
        "description": "numpt"
    },
    "@primnum": {
        "prefix": "prn",
        "body": [
            "@primnum"
        ],
        "description": "primnum"
    },
    "@numprim": {
        "prefix": "npr",
        "body": [
            "@numprim"
        ],
        "description": "numprim"
    },
    "i@grp_": {
        "prefix": "grp",
        "body": [
            "i@grp_${0:name}"
        ],
        "description": "group"
    },
    "@N": {
        "prefix": "nn",
        "body": [
            "@N"
        ],
        "description": "Normal"
    },
    "@force": {
        "prefix": "ff",
        "body": [
            "@force"
        ],
        "description": "force"
    },
    "@OpInputN": {
        "prefix": "opi",
        "body": [
            "@OpInput${0:N}"
        ],
        "description": "N: 1..."
    },
    "@opinputN_attrib": {
        "prefix": "opi",
        "body": [
            "@opinput${1:N}_${0:attrib}"
        ],
        "description": "N: 0..."
    },
    "chramp": {
        "prefix": "chr",
        "body": [
            "chramp(${1:channel}, ${0:ramp})"
        ],
        "description": "chramp"
    },
    "rand": {
        "prefix": "rnd",
        "body": [
            "rand(${0:seed})"
        ],
        "description": "rand function"
    }
}

キーバインドの設定

これもVimキーバインドなので不要な方は無視の方向で。

f:id:kickbase:20190211213612j:plain

f:id:kickbase:20190211213625j:plain

keybindings.json

// 既定値を上書きするには、このファイル内にキー バインドを挿入します
[
    {
        "key": "ctrl+m",
        "command": "acceptSelectedSuggestion"
    },
    {
        "key": "ctrl+j",
        "command": "selectNextSuggestion",
        "when": "editorTextFocus && suggestWidgetMultipleSuggestions && suggestWidgetVisible"
    },
    {
        "key": "ctrl+p",
        "command": "selectPrevSuggestion",
        "when": "editorTextFocus && suggestWidgetMultipleSuggestions && suggestWidgetVisible"
    },
    {
        "key": "ctrl+i",
        "command": "-extension.vim_ctrl+i",
        "when": "editorTextFocus && vim.active && vim.use<C-i> && !inDebugRepl"
    },
    {
        "key": "ctrl+i",
        "command": "-expandLineSelection",
        "when": "textInputFocus"
    },
    {
        "key": "ctrl+i",
        "command": "jumpToNextSnippetPlaceholder",
        "when": "editorTextFocus && vim.active && vim.use<C-i> && !inDebugRepl"
    }
]

まとめ

割といいんじゃないでしょうか。VS Code。コードフォーマットが実現できたらもっといいなーと思うのでご存知の方は教えていただけると泣いて喜びます。

*1:以前はHoudini Edit in External Editorというのを使っていました

*2:先ほど作ったばかりなので抜けや間違いあるかと思います。随時アップデートしていきます