So I've been hacking on some
Scala in my spare time, and one of the problems I've been having is finding proper IDE support for the language. I like being able to ctrl-click or cmd-click on a class or method to instantly jump to the definition of that class or method. For Classes, IntelliJ IDEA's Scala plugin does alright. But for methods, it seems pretty lost at times,
this question on the
scala-user mailing list pretty much sums up my problem:
For instance, I'm using the mongo-scala-driver and a statement like this:
val transcripts = db.getCollection("transcripts") of Transcript
It can't tell me where "of" is defined. Or:
for {acct <- account from dbo} yield new Expense(acct)
It has no clue where "from" is declared.
Also, because of Scala syntax I'm not entirely sure if those are imported methods from an Object or methods from the class the method proceeds? For instance is "from" a method imported from an Object imported using SomeObject._ or a method of the account class?
So, I've been coping by downloading all the source code for the libraries I'm using and issuing find + grep commands on the code base. For instance:
$ find . -name *.scala -exec grep 'def from' {} \;
def from(dbo: DBObject) = unapply(dbo)
def from(dbo: DBObject) = unapply(dbo)
def from(dbo: DBObject) = unapply(dbo)
def fromMap(m: Map[String,Any]): DBObject = {
Ah crap, no filename! Ok, well I could just re-issue the grep command with the -l option to tell it to list file names instead of the matched lines:
find . -name *.scala -exec grep -l 'def from' {} \;
But if I had a lot of hits on my original search, it might be tough to determine which line came from which file. Well, it turns out you can implement this trick with grep such that if you specify more than one file to look in, grep will display which file it got its match from, hence you getting listing of the line which matched and what file it came from:
$ find . -name *.scala -exec grep 'def from' /dev/null {} \;
./src/main/scala/com/osinka/mongodb/shape/Field.scala: def from(dbo: DBObject) = unapply(dbo)
./src/main/scala/com/osinka/mongodb/shape/Field.scala: def from(dbo: DBObject) = unapply(dbo)
./src/main/scala/com/osinka/mongodb/shape/Field.scala: def from(dbo: DBObject) = unapply(dbo)
./src/main/scala/com/osinka/mongodb/wrapper/DBObj.scala: def fromMap(m: Map[String,Any]): DBObject = {
In this case we tell grep to search in both the file provided by find: {} and /dev/null. It's never going to find a match in /dev/null, so it will always display the match if it came from a file provided by find.