header

2013年9月21日土曜日

Scala & ensime & Emacsでandroidにhello world


Javaはつかいたくないけどandroidでなにかアプリを作りたいとおもっていて、
Scalaがよさそうとおもってhello worldのプログラムを実機にインストールす
るまでできた。これはそのメモ(環境 Ubuntu 12.04 LTS & Emacs 24.3.1)

環境変数

JAVAHOME を設定した

export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/

sbtのインストール

sbt(simple build tool)の略らしい、scalaのバージョン管理するにもいいらし
いのでインストールした。別に下のコードを書く必要はないけど、sbt の
version 0.13-SNAPSHOTだとandroid-pluginがうまく動いてくれないようなので
0.12系のほうが良い。(Sat Sep 21 08:10:27 2013時点 https://github.com/jberkel/android-plugin/issues/190)

local SBT12='http://repo.scala-sbt.org/scalasbt/sbt-native-packages/org/scala-sbt/sbt//0.12.4/sbt.deb'
cd ${HOME}/opt/local/
wget ${SBT12}
sudo dpkg -i sbt.deb

ensime

slimeも必要かもしれない.
el-getをつかっているなら M-x el-get-install ensime でインストールできると思う。
ただ、インストール後のbuild スクリプトがsbt update stageとなっているので、sbt
インストール後の方がいい。

android plugin

Android pluginのGetting startedをみてそのままgiter8をインストール

curl https://raw.github.com/n8han/conscript/master/setup.sh | sh
~/bin/cs n8han/giter8


あとは

~/bin/g8 jberkel/android-app
> Template for Android apps in Scala

> package [my.android.project]:
> name [My Android Project]: My_Android_Project
> main_activity [MainActivity]:
> scala_version [2.9.2]: 2.10.2
> api_level [10]: 18
> useProguard [true]:
> scalatest_version [1.8]:


でプロジェクトは作れる
nameのところはスペースが入ってるとうまく行かなかった。

project

~/bin/g8 jberkel/android-appコマンドでひな形をつくったら、

sbt
android:package-debug


をしてパッケージ化しようとしけどエラーがでた。

> android:package-debug
[info] Updating {file:/home/ck/Development/yy_android_project/}YY_Android_Project...
[info] Wrote /home/ck/Development/yy_android_project/target/scala-2.10/src_managed/main/scala/my/android/project/TR.scala
[info] Resolving org.scalatest#scalatest_2.10;1.8 ...
[warn] module not found: org.scalatest#scalatest_2.10;1.8
[warn] ==== local: tried
[warn] /home/ck/.ivy2/local/org.scalatest/scalatest_2.10/1.8/ivys/ivy.xml
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/org/scalatest/scalatest_2.10/1.8/scalatest_2.10-1.8.pom
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.scalatest#scalatest_2.10;1.8: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last YY_Android_Project/*:update for the full output.
[error] (My_Android_Project/*:update) sbt.ResolveException: unresolved dependency: org.scalatest#scalatest_2.10;1.8: not found
[error] Total time: 1 s, completed Sep 21, 2013 8:29:12 AM


scalatest のページを見ると2.0.M8が最新っぽいので、./project/Build.scalaの
libraryDependencies を変更(Errorからググって発見)

// libraryDependencies += "org.scalatest" %% "scalatest" % "1.8" % "test"
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M8" % "test"


その後もう一度ためしたが何かエラーがでて、android sdkの
build-tools/android-4.3/dx と同じディレクトリのapptをplatform-toolsの中
にリンクを作成した。


これでsbt 'android:package-debug'(これはバッチモードの書き方)でapkファ
イルを作成できた。あとは作成された apk ファイルをadb install
filepath.apk のように指定すれば実機にも転送できた(もちろん事前に
android-ruleの追加とかはしてますが)

ensime

それとensimeを使うために./project/plugins.sbtにensimeのpluginを追加した。
(ensimeの上の2つの文は勝手に設定されていた)

resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns)

addSbtPlugin("org.scala-sbt" % "sbt-android-plugin" % "0.6.2")

addSbtPlugin("org.ensime" % "ensime-sbt-cmd" % "0.1.0")


その後

sbt 'ensime generate'


で .ensime ファイルができてるので、.scalaのファイルを開いたあと M-x
ensime でensimeが利用できるようになる。


2013年9月7日土曜日

英語環境で文字を大文字にキャピタライズする拡張auto-capitalize.elを導入し た & aspellの個人辞書からもキャピタライズするようにした


Emacsで文章を書くときはauto-fill-modeなど色々拡張があると思いますが、 auto-capitalize.el という自動でキャピタライズしてくれる拡張を見つけたので導入しました。
がSKKを起動したあとこの拡張を使うとエラーが出て動かなかったので,
コードを修正してGitHubに公開しました。
Googlingしたのですが、emacswiki版のものが最新のようだったのでそれからフォークしました。(もし最新版をご存知の方がいたら教えていただけると助かります)

機能

モードがオンの状態だと、、、


  • コメント行のはじめの文字を大文字にしてくれる
  • ドットの後の文字を大文字ににしてくれる
  • auto-capitalize-words 変数に登録した文字を大文字にしてくれる。
    例えばGitHubと登録してあったら

    github


    と打った直後にGitHubに変換してくれる。

インストール

自分がEl-Get環境がメインになってるのでそのインストール方法から

(push '(:name auto-capitalize
:type git
:url "https://github.com/yuutayamada/auto-capitalize-el.git"
:load-path "./")
el-get-sources)


上のコマンドを設定ファイルに書いてC-x C-eなどで評価したあとM-x el-get-install auto-capitalizeでインストールできます。
もう一つの方法として、gitからクローンする方法

# クローン
cd /path/to/install/directory
git clone https://github.com/yuutayamada/auto-capitalize-el.git

設定

これが正解というのはないかもしれませんが一応自分の設定をのせておきます。そんなに確認できていませんが、この記事を書いているorg-modeではうまく動いています。
ソースコードの中ではコメント部分にいる間だけキャピタライズして欲しいのでそれ用の関数を書きました。

(defvar programing-hooks
'(c-mode-hook
c++-mode-hook
coffee-mode-hook
cperl-mode-hook
css-mode-hook
emacs-lisp-mode-hook
lisp-mode-hook
sh-mode-hook
js2-mode-hook
jade-mode-hook
python-mode-hook
ruby-mode-hook))

(defvar my/programming-mode nil
"Use this variable to know whether current major-mode is mode for programming.
If it is non-nil mean the mode is mode for programming.")

(loop for hook in programing-hooks
do (add-hook hook
'(lambda ()
(setq-local my/programming-mode t))))

(defun my/switch-auto-capitalize-mode ()
(if my/programming-mode
(if (equal font-lock-comment-face
(nth 1 (text-properties-at (point))))
(turn-on-auto-capitalize-mode)
(turn-off-auto-capitalize-mode))))

(defadvice self-insert-command
(around ad-turn-on-auto-capitalize activate)
(unless (minibufferp)
(my/switch-auto-capitalize-mode))
ad-do-it)

;;(defvar my/aspell-words-capital-only (my/get-aspell-capital-words))

(setq auto-capitalize-words `("I"
;; ,@my/aspell-words-capital-only
))

(setq auto-capitalize-predicate
'(lambda ()
;; Prevent auto-capitalize if return nil
(and (not buffer-read-only)
(or (not skk-mode) skk-latin-mode))))

(add-hook 'text-mode-hook
'(lambda ()
(turn-on-auto-capitalize-mode)))


auto-capitalize-words変数にリスト上の文字列をしてすることでその文字が入力されたときは大文字にしてくれます。


例:
i -> I

ちょっとハック

上のコードの中でコメントアウトしてる部分が気なると思いますが、
ispell/aspellで登録した単語から大文字にしたらいいと思いコードを書いてみました。

(eval-when-compile (require 'cl))
(defun my/get-buffer-string-from (file)
(lexical-let* ((current (current-buffer))
(aspell-buffer (find-file-noselect file))
words)
(switch-to-buffer aspell-buffer)
(setq words (buffer-substring-no-properties (point-min) (point-max)))
(switch-to-buffer current)
words))

(defun my/get-aspell-capital-words ()
(loop with personal-dict = (my/get-buffer-string-from "~/.aspell.en.pws")
with words = (split-string personal-dict "\n")
with case-fold-search = nil
for word in words
if (string-match "[A-Z]" word)
collect word))


aspellの辞書の保存先は自分以外の環境はわからないので適当に変えてください。
上の関数を定義後コメントアウトしたところをコメントイン(この言い方でいいんですかね?)すればaspellの個人辞書の大文字の単語を含めることができます。
改行区切りのファイルなら他のaspellでなくても大丈夫だと思います。

感想

英語書くのが多い人はいいのではないかと思います。シフトキーを押す回数が気持ちへったきがします。auto-fill-modeのように標準で入ってもいいくらいだと思うのですがなんで入ってないんですかね?多分人名辞典かなんかからもっとインポートすればさらに便利になるのではないかと思います。

ダメなところ


  • 書いてる途中で気づいたのですが、El-Getなどのハイフンの入ったものはリストに登録してあってもうまくキャピタライズしてくれません。
  • コメント行では最初の文字をキャピタライズしてくれません。
    (誰かcomment-start変数をハックして僕にpull requiestを…)


使い始めて0.5日くらいですが今気になるのはこれくらいです。もし良かったら使ってみてください。


Popular Posts

Blogger templates

Blogger news