flymakeを使ってAlloyのTSSをリアルタイム文法チェック

Alloyのtssの文法ってよく分からんですね。css-modeあててもjs2-modeをあててもエラーばっか吐くし、快適にコーディングできん。

ということでちょっと調べてみた。

Alloyのソースコード探していたらgrammerのとこにtss.pegjsってのがあって、ヘッダを読んでみるとTSS parser based on JSON parserって書いてあったので基本的にはJSONらしい。

それにしては{で始まらないよなぁとソースコードを追いかけていくとcompilerUtils

// Add enclosing curly braces, if necessary
contents = /^\s*\{[\s\S]+\}\s*$/gi.test(contents) ? contents : '{' + contents + '}';

ってあって、要するに{で始まってない場合ファイルのコンテントを{}で囲むことになっているらしい。それからtssはキー値を""で囲まなくてもいいんだけど、囲んでも別に問題なかったりする。

結論としてはJSONで書いておけば、即時構文チェックとかシンタックスハイライトとか効かせられていいんじゃないかと。

つまり

"Label": {
  font: {fontSize: 20, fontFamily: "Helvetica Neue"},
  color: "#999"
}

って書いてるところを、最初から

{"Label": {
  "font": {"fontSize": 20, "fontFamily": "Helvetica Neue"},
  "color": "#999"
}}

って書くようにすれば、事前に構文のエラーを潰せて気持ちがいい。

Emacsの設定

json-modeを使ってみますが、package.elでは入れられないのでgit cloneしてrequireします。javascript-modeを継承しているのでTabの設定なんかはそっちの設定に従う。

次にFlymakeの設定をする。構文チェックにjslintを使うのでインストールしてない場合には

npm install -g jslint

で入れます。

Emacsのほうの設定はこんな感じ。tabはスペース2個分(個人的な好み)にした。それからelectric-pair-modeも入れてるので{},""をよろしくやってくれる。

;; JSON
(require 'json-mode)
(add-to-list 'auto-mode-alist '("\\.tss$" . json-mode))
(add-hook 'json-mode-hook 'electric-pair-mode)
(add-hook 'json-mode-hook '(lambda ()
                 (setq js-indent-level 2)
                 ))

(when (load "flymake" t)
  (defun flymake-jslint-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
               'flymake-create-temp-inplace))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
      (list "jslint" (list "--terse" local-file))))

  (setq flymake-err-line-patterns
    (cons '("^\\(.*\\)(\\([[:digit:]]+\\)):\\(.*\\)$"
        1 2 nil 3)
          flymake-err-line-patterns))

  (add-to-list 'flymake-allowed-file-name-masks
               '("\\.tss\\'" flymake-jslint-init)))

(load-library "flymake-cursor")

この設定で少し使ってみる。

Emacs+titanium cli+alloyでiPhoneアプリを開発する

静岡javaScript勉強会 #2に参加されるみなさんこんにちは、参加されないみなさんもこんにちは。僕は11月のすべての土曜日を留守にして家族の顰蹙を買うという重圧に耐え切れずに早々に離脱してしまいましたので朝からお家でjsってます。

ところで、@tomofの「Backbone.js入門」面白かったですか?よっしゃーいっちょおとうさんもbackbone.jsでウェブアプリケーションつくっちゃうぞーっていう気になりましたか?はいそうですか、そうですよね。ついでに、その勢いでBackbone.jsっぽい開発のノリでiPhoneアプリを開発できたら面白いと思いません?思いますよね。

やりましょう、Alloyで!(孫社長風味でよろしく)

というような内容のエントリです。

1351985625

Titanium CLIとAlloyのインストール

Titanium CLIはTitaniumで開発するためのコマンドラインのツールで、AlloyはTitaniumのためのMVCフレームワークですが、両方共Node.jsのv0.8以上がインストールされていればnpmでインストールできるはずです。

npm install -g titanium
npm install -g alloy

うまくいかない場合は下のサイトを参考にしてください。

エディタ

EmacsでもvimでもST2でも好きなモノを使えば良いとおもいますが、僕はEmacs(24)をつかっています。でnxmlモードにzencoding-modeをあててあります。入ってない場合はM-x list-packaegesでzencoding-modeを選んでインストールしたらinit.elに下の内容を追記しておけばいいです。

(add-hook 'sgml-mode-hook 'zencoding-mode) 
(add-hook 'nxml-mode-hook 'zencoding-mode)

他にはjavascriptの開発用にjs2-modeを入れているのとcoffeeモードにflymakeが効くようにしてありますが今回の内容では必要ありません。

追記121118: CoffeeScriptを使って開発する方法

開発の流れ

最初にtitaniumコマンドでプロジェクトの雛形をつくります

$ titanium create
Titanium Command-Line Interface, version 3.0.13
Copyright (c) 2012, Appcelerator, Inc.  All Rights Reserved.

Please report bugs to http://jira.appcelerator.org/

Target platforms: (android,ios,ipad,iphone,mobileweb) iphone
App ID: com.example.tabsample
Project name: tabsample

[INFO] Creating Titanium Mobile application project
[INFO] Project 'tabsample' created successfully in 276ms

プロジェクトのディレクトリに移動してalloyの雛形をつくります。

$ cd tabsample/
$ alloy new
       .__  .__                
_____  |  | |  |   ____ ___.__.
\__  \ |  | |  |  /  _ <   |  |
 / __ \|  |_|  |_(  <_> )___  |
(____  /____/____/\____// ____|
     \/                 \/
Alloy by Appcelerator. The MVC app framework for Titanium.

[INFO] Installed "ti.physicalSizeCategory" module to tiapp.xml
[INFO] Installed "ti.alloy" plugin to tiapp.xml
[INFO] Deployed ti.alloy compiler plugin to plugins/ti.alloy/plugin.py
[INFO] Deployed ti.alloy hooks to plugins/ti.alloy/hooks
[INFO] Generated new project at: app

ここからEmacsを使っていきます。まずはapp/views/index.xmlを修正します。中身を全部消してzencodingでさくっと用意します。zencodingはC-returnで起動させて

Alloy>TabGroup>(Tab#tab icon title>Window#window title backgroundColor>Label#lable)*2

みたいにワンライナーで書けるので便利すぎです。

emacs-zen

zencodingで大まかにスキャフォールドを用意したら、アトリビュートなんかを設定します。ちなみに画像はここから取ってきてapp/assets/iphone/に起きました。

<Alloy>
    <TabGroup>
        <Tab id="tab1" icon="KS_nav_views.png" title="Tab 1">
            <Window id="window1" title="Tab 1" backgroundColor="#fff">
                <Label id="label1">
          I am Window1
                </Label>
            </Window>
        </Tab>
        <Tab id="tab2" icon="KS_nav_ui.png" title="Tab 2">
            <Window id="window2" title="Tab 2" backgroundColor="#fff">
                <Label id="label2">
          I am Window2
                </Label>
            </Window>
        </Tab>
    </TabGroup>
</Alloy>

app/styles/index.tssはLabelの設定だけ。

    "Label": {
    font: {fontSize:20, fontFamily:"Helvetica Neue"},
    color: "#999"
}

tssにはどのモードをアサインするのがいいのでしょうか?誰か知っていたら教えて下さい。(追記121117 json-modeあててみた)

iOSシミュレータを起動

プロジェクトのトップディレクトリで

$ alloy run

するとシミュレータが立ち上がります。素敵ですね。これで、雛形作ってシミュレータを動かすところまでできました。あとはapp以下を良い感じにいじってイケてるアプリを作るだけですね。

ti-alloy

シミュレータが立ち上がるまでに結構待たされるのでストレスを感じますが、それは僕のmacが遅いからですね。はやく買い換えたい。

おまけ(Alloyの開発にJadeを使う)

@k0sukeyAlloyJadeという素敵なものがあることを教えてもらいました。Jade派の僕としては非常に惹かれるので後で試そうかなと思っています。

local-set-keyに出てくる(interactive)

よく分からないでコピペで増やしたlocal-set-keyだが

(local-set-key "\C-j" (lambda () (interactive) (insert " -> ")))

と、ラムダ式に(interactive)が含まれている。試しに(interactive)を排除して

(local-set-key "\C-j" (insert " -> ")))

を評価(C-x C-e)してC-jを押してみると

Wrong type argument: commandp, (lambda nil (insert " -> "))

とミニバッファにエラーが出力される。commandpとは一体なんだろうか?と f1 f commandp

(commandp FUNCTION &optional FOR-CALL-INTERACTIVELY)

commandかどうかを判定する関数らしいが、よく分からんのでf1 f local-set-keyで見てみると

(local-set-key KEY COMMAND)

関数ではなくてCOMMANDである必要があるらしい。

コマンドとは、定義の最初にinteractiveスペシャルフォームが置かれた関数ですEmacsLISPテクニックバイブル p.79

EmacsLISPテクニックバイブルにちゃんと書いてあった。

ProductName Emacs Lispテクニックバイブル
るびきち
技術評論社 / 3129円 ( 2011-11-26 )


最近elispをよく読むのでかなりお世話になっている本だ。

CoffeeScriptでFlymake

Emacs24にしたので再設定

coffeelintのインストール

npm install -g coffeelint

coffee-modeはM-x list-packagesからiで選んでxで実行

Tabの設定が変だったので、init.elにちょっと追加。ついでにアローとかファットアローを挿入するキーバインドも設定。

(add-hook 'coffee-mode-hook '(lambda ()
  (make-local-variable 'tab-width)
  (set 'tab-width 2)
  (local-set-key "\C-j" (lambda () (interactive)(insert " -> ")))
  (local-set-key "\M-j" (lambda ()(interactive)(insert " => ")))))

flymakeはこの通りに設定しておけばでオッケー

HaskellでFlymake

Emacs24だったらghc-modを使うのが簡単。

まずはコマンドラインツールをインストール

cabal install ghc-mod hlint

package.elからflymake,haskell-mode,ghcを入れる。M-x list-packagesでiで選んでxでインストール開始

~/.emacs.d/init.elの設定

;; haskell ghc-mod
;; https://github.com/kazu-yamamoto/ghc-mod
(autoload 'ghc-init "ghc" nil t)
(add-hook 'haskell-mode-hook (lambda () (ghc-init) (flymake-mode)))

こんだけで快適な環境が手に入る。

Emacsでコード補完にJediを使う (Python)

昨日ac-python入れてみたんだけど、@kozo2jediがいいと教えてもらったので、早速使ってみた。

なんも考えないで設定すると/usr/bin/pythonを見ているようで、import errorが起きていたので、JEDI:SOURCE-DIR/env/bin/python に/usr/local/bin/pythonのシンボリックリンク張って解決

それから

(add-hook 'python-mode-hook 'jedi:ac-setup)

がうまく動かなかったので、jedi:setupのほうからC-tabで補完させて使っている。

それから下の順番で読ませないと動かないのはpackage.elのせいなのかなぁ。

;; jedi
(add-hook 'python-mode-hook 'jedi:setup)
(setq jedi:setup-keys t)
(require 'jedi)

候補が表示されるのはac-pythonと似たような感じ。

jedi

引数が表示されるのはかなり便利だ。Flaskのmodelとか引数の順番結構忘れるので。

jedi

ac-pythonで補完リストが表示されない(Emacs24)

pythonのモジュールの補完が出来ればいいなぁと思い、ac-pythonを入れてみたのだけどwindowに補完候補が表示されない。

Pythonのバッファを開いてみると、以下のようにemacs.completeによって補完候補がきちんと 返されている。

ac-python

動的略語展開(M-/,C-o)のほうで拾えるのでそんなに困らないんだけど、理由がわからないのでちょっと気持ち悪い。

Emacsの短形領域が便利すぎる

Emacs Rocks! Episode 01: From var to thisを見ていて、これってEmacsで複数行の行頭空白を削除する方法の逆パターンか!と思ったのだがkill-rectangleはC-x r kにアサインされていることを知った。

それから、C-sで検索すると検索開始位置が勝手にマークされるのを知らなかった。もっと使おうっと。

このブログはmarkdown記法で書いているのでコードを貼り付けるときにスペース4文字挿入しないといけないんだけど、文字幅0の短形領域を選択すれば簡単にspace x 4を挿入できる。いままではdmacro.elで繰り返してたけど、C-x r tのやり方のほうが快適だ。

使い始めると短形領域をkillしたりyankしたりしたくなるとおもうんだけど、それはC-x r k(y)でオッケー

参考

Emacsを23系から24.2に変更中

そのままでは23での.emacs.dの設定が動かなかったので、スクラッチから書き直している。

大きく変えたのは

  • パッケージの管理がpackage.el (+ auto-install.el)にした
  • テーマを組み込みのにした

magitとかjs2-modeはインストールしただけで動くし結構楽かな。一方でmaximize-windowっていうコマンドが使えるようになったのだけどosxでは動かないし、window-sizeを変更すると上の何行かにアクセスできなくなったりして困っている。

ちょうどいいのでGitHubで管理するようにしたけどコマンド一発で環境ができるようにしたいなぁ。

less-css-modeを入れた

最近Twitter-Bootstrapを使っているのでEmacsのLESSモードが欲しくなった。

site-lispでgit cloneしたら

(setq load-path (cons "~/.emacs.d/site-lisp/less-css-mode" load-path))
(setq exec-path (cons (expand-file-name "~/.nvm/v0.8.0/bin") exec-path))
(require 'less-css-mode)

Flymakeも走るので快適だ。

less-css-mode