yasnippet-java-mode (topcoder用)

  • お決まりのfor文をCみたいにマクロ使ってREP(i, n)と短く書きたい
  • javaじゃ無理
  • じゃあもうタイプ量が減ればいいよ
  • yasnippetで展開させればいいんじゃね?
  • ついでによく使いそうなコレクションの宣言もさくっと書けるようにしてみよう


import java.util.*; してること前提です。

導入

yasnippetが必要です。あとemacsも必要です。
Google Code Archive - Long-term storage for Google Code Project Hosting.


ファイルはgithubに置いてあります。
GitHub - k-chop/yasnippet-java-topcoder: yasnippet java-mode for topcoder. These snippets are placed in the public domain.


git cloneして、

git clone git://github.com/whelmaze/yasnippet-java-topcoder.git

java-modeディレクトリ以下をyas/load-directoryに設定したディレクトリにぶち込むと、java-modeでこのスニペットが使えるようになります。
githubのサイト右上にあるDownload Sourceから、zipで入手することもできます。

for文
fori

↓展開

for(int i = [1]; i [2] ; i++) {
    [3]
}

TABキーを押していくと[1]->[2]->[3]の位置に移動するようになってます。
foriのほかにforj, fork, forlを用意してあります。

コレクション
cal  //[c]ollection [a]rray[l]ist の略

↓展開

List<[Type]> [name] = new ArrayList<Type>();

TABキーを押していくと[]で囲んである部分に順番に飛ぶようになってます。
二度目に出てくるTypeの部分は、片方の入力と連動して変更されるので同じ型名を二度書く必要はありません。
展開するキーはコレクションの頭文字なので楽に使えると思います。


他のコレクションも同じように展開できます。

chs => Set<[Type]> [name] = new HashSet<Type>();       // [c] [h]ash[s]et

cll => List<[Type]> [name] = new LinkedList<Type>();   // [c] [l]inked[l]ist

chm => Map<[Key], [Value]> [name] = new HashMap<Key, Value>(); // [c] [h]ash[m]ap

cad => Deque<[Type]> [name] = new ArrayDeque<Type>();  // [c] [a]rray[d]eque

QueueやStackはDequeがあればいらない気がするので入れていません。


List, Setは末尾にそれぞれi, d, l, sをつけると、Type部分にInteger, Double, Long, Stringが入力済みのものを展開します。

cali => List<Integer> [name] = new ArrayList<Integer>(); // [c] [a]rray[l]ist<[i]nteger>

chss => Set<String> [name] = new HashSet<String>();      // [c] [h]ash[s]et<[s]tring>
ついでに
sb   => StringBuilder [name] = new StringBuilder();

sc   => Scanner [name] = new Scanner();

new  => [Type] [name] = new Type();

arr  => [Type][] [name] = new Type[];

2arr => [Type][][] [name] = new Type[][];

sbtのproguardプラグインを使う

**注意**

この記事は既に情報が古くなっていますので参考にするべきじゃないです。
未だに0.10以前のsbtを使っているなんて人ははやいとこ最新版に変えた方が幸せになれます。

sbt0.11以降対応のproguardプラグインはこちら

GitHub - aolshevskiy/xsbt-proguard-plugin: A plugin for XSBT to facilitate the use of ProGuard to create single jars for XSBT-managed projects

                                                                                  • -

githubのサイトはこちら。
GitHub - nuttycom/sbt-proguard-plugin: A plugin for SBT to facilitate the use of ProGuard to create single jars for SBT-managed projects.


sbtからコマンドひとつでproguardが実行できるようになります。
simple-build-tool-0.7.3で動いてます。たぶん0.7.4でも動きます。


まずはproject/plugins/Plugins.scalaを以下の内容で作ります。

import sbt._

class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
  val proguard = "org.scala-tools.sbt" % "sbt-proguard-plugin" % "0.0.2"
}

保存したらreloadを忘れずに。


お次はproject/build/Project.scalaを以下の内容で作ります。

import sbt._

class Project(info: ProjectInfo) extends ProguardProject(info) {
  def keepMainClass = """
-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}
"""
  override def proguardDefaultArgs =
    "-dontwarn" :: "-dontoptimize" :: "-dontobfuscate" :: keepMainClass  ::  proguardOptions
}

メインメソッドがあるクラスを-keepするように設定を追加しています。
ProjectがextendsしているProguardProjectは
project/plugins/src_managed/sbt-proguard-plugin-0.0.2にソースが置いてあります。
githubのサイトからも読めます。


reloadしたら
proguard
で実行。
警告がどばっと出てきますが無視。
何も問題がなければ、targetフォルダ内に最適化されたjarファイルが出来上がってます。


出来上がるjarにscala-library.jarを含めたいなら、scala-library.jarをlibフォルダにぶち込んどけばおkです。

  • 追記

windowsXPでやってみたところ、JAVA_HOMEのパスに空白が含まれているとダメなようです。
(空白があると、実行時にparseに失敗したぞコラァ!とproguardのConfigurationParserが怒り出す)


この場合は、
%JAVA_HOME%/lib/rt.jarを適当な場所(もちろんパスに空白が含まれていないこと)にコピーして、
project/build/Project.scala

override def rtJarPath = Path.fromFile("c:/home/tmp/rt.jar")  //←rt.jarの絶対パス

を追加してあげれば動くようになります。

SRM 463 DIV2

904 -> 942

  ( ^ω^) ……
   V ノ> 
   ││ 
   ┛┗  
問題 結果 備考
250 Passed System Test 101.41pt
500 Passed System Test 408.56pt
1000 Opened

撃墜はなし。部屋の1000が次々ブチ落とされていくのを呆然と眺めてました。

続きを読む