Coder Social home page Coder Social logo

emacs-scala-mode's Introduction

emacs-scala-mode

The mode intends to provide basic emacs support for the Scala language, including:

  • local indenting of code, comments and multi-line strings
  • motion commands
  • highlighting

See also emacs-sbt-mode.

Installation

The preferred mechanism is via MELPA and use-package as per our Learning Emacs guide:

(use-package scala-mode
  :interpreter
    ("scala" . scala-mode))

Multi-line comments

The start of a multi-line comment is indented to the same level with code.

By default, if a multi-line comment begins with /* it is considered to be a Scaladoc comment. Scaladoc comments are indented according to the Scaladoc style guide.

/** This is a Scaladoc comment.
  * 2nd line.
  */

Alternatively, if the configurable variable scala-indent:use-javadoc-style is set to t, multi-line comments beginning with /** will be indented according to the Javadoc style, wherein all following lines are indented under the first asterisk.

/**
 * This is a Javadoc-style comment.
 * 2nd line.
 */

All other multi-line comments are indented under the first asterisk.

/**
 * Supercalifragilistic-
 * expialidocious!
 */

/*
 A comment
 */

Typing an asterisk in multi-line comment region, at the start of a line, will trigger indent. Furthermore, if the configurable variable scala-indent:add-space-for-scaladoc-asterisk is t (default) and the asterisk was the last character on the line, a space will be inserted after it. If you type a forward slash after the automatically inserted space, the space is deleted again so that you can end the comment without deleting the space manually.

Filling (i.e. word wrap)

Paragraph filling is supported for comments and multi-line strings. Auto-fill is not supported yet.

To re-fill a paragraph, use the fill-paragraph command ( M-q ). As always, the column at which to wrap is controlled by the fill-column variable, which you set it with the set-fill-column command. To set the default, you use the customize-variable command or a mode-hook.

Motion

Emacs commands forward-sexp and backward-sexp ( M-C-f, M-C-b ) motion commands will move over reserved words, literals, ids and lists.

Text paragraph motion (i.e. forward-paragraph, backward-paragraph) works inside comments and multi-line strings, and it respect Scaladoc's wiki-style markup.

scala-syntax:beginning-of-definition and scala-syntax:end-of-definition move the cursor forward and backward over class, trait, object, def, val, var, and type definitions. These functions are assigned to the buffer local variables beginning-of-defun-function and end-of-defun-function which makes it so that the beginning-of-defun and end-of-defun functions behave in a way that is appropriate to scala. These functions are not currently able to support some of the more advanced scala definition types.

Highlighting

The highlighting of variable definitions, such as

var test = "some mutable variable"

now result in the variable name ("test" above) to be highlighted using the variable scala-font-lock:var-face. Per default, the value of scala-font-lock:var-face is 'font-lock-warning-face. You can always change the highlighting of vars by changing scala-font-lock:var-face through the Emacs face customization (use M-x customize-face).

Very complex scala files may need the following in your emacs init (.emacs, etc):

;; For complex scala files
(setq max-lisp-eval-depth 50000)
(setq max-specpdl-size 5000)

imenu

scala-mode supports imenu, a library for accessing locations in documents that is included in emacs 24. The custom variable scala-imenu:should-flatten-index controls whether or not the imenu index will be hierarchical or completely flat. The current iMenu implementation only goes one level deep i.e. nested classes are not traversed. scala-mode's imenu support depends heavily on the scala-syntax:end-of-definition and scala-syntax:beginning-of-definition functions, and as such, it shares their limitations.

Joining lines (delete indentation) and removing horizontal whitespace

Scala-mode defines its own scala-indent:join-line and scala-indent:fixup-whitespace functions.

Unlike the normal join-line (aka delete-indentation), scala-indent:join-line detects the comment fill-prefix and removes it.

The scala-indent:fixup-whitespace first removes all horizontal whitespace, then adds one space the context requires none to be present (before semicolon, around dot, after ( or [, before ) or ], etc).

Indenting

Where four developers meet, there are four opinions on how code should be indented.

scala-mode supports 2^4 different ways of applying local heuristics to indentation.

Note that when using sbt-scalariform, your local indentation rules will be overwritten.

Run-on lines

Provided by scala-indent:default-run-on-strategy

The indenting engine has three modes for handling run-on lines. The reluctant (default) mode is geared toward a general style of coding and the eager for strictly functional style. A third mode called operators is between the two.

The difference between the modes is how they treat run-on lines. For example, the eager mode will indent map in the following code

val x = List(1, 2, 3)
 map(x => x + 1)

The operators and eager modes will indent the second row in the following code, as the first line ends with an operator character.

val x = 20 +
  21

The reluctant mode (default) will not indent the line in either case. However, all three modes will indent the second line in these examples as it is clear that the first line cannot terminate a statement.

val x = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).
  map (x => x + 1) // last token of previous line cannot terminate a statement

val y = (List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
           map (x => x + 1)) // inside 'newlines disabled' region

You can use empty lines in the eager mode to stop it from indenting a line. For example

val x = foo("bar")
           ("zot", "kala") // indented as curry

val y = foo("bar")

("zot", "kala") // a tuple

However, in all three modes pressing the tab key repeatedly on a line will toggle between the modes.

Value expressions

Provided by scala-indent:indent-value-expression

When this variable is set to nil (default), body of a value expressions will be indented in the traditional way.

val x = try {
  some()
} catch {
  case e => other
} finally {
  clean-up()
}

However, when the variable is set to t, the body will be indented one extra step to make the val, var or def stand out. For example:

val x = try {
    some()
  } catch {
    case e => other
  } finally {
    clean-up()
  }

Parameter lists

Provided by scala-indent:align-parameters

When this variable is set to nil (default), parameters and run-on lines in parameter lists will not align under or according to the first parameter.

val y = List( "Alpha", "Bravo",
  "Charlie" )

val x = equals(List(1,2,3) map (x =>
  x + 1))

When the variable is set to t, the same will be indented as:

val y = List( "Alpha", "Bravo",
              "Charlie" )

val x = equals(List(1,2,3) map (x =>
                 x + 1))

Expression forms: if, for, try

Provided by scala-indent:align-forms

When this variable is set to nil (default), if, for and try forms are not aligned specially.

val x = if (kala)
  foo
else if (koira)
  bar
else
  zot

val x = try "1".toInt
catch { case e => 0}
finally { println("hello") }

val xs = for (i <- 1 to 10)
yield i

When the variable is set to t, the same will be indented as:

val x = if (kala)
          foo
        else if (koira)
          bar
        else
          zot

val x = try "1".toInt
        catch { case e => 0}
        finally { println("hello") }

val xs = for (i <- 1 to 10)
         yield i

Prettify-Symbols

Scala-mode has a preconfigured list of prettify-symbols rules. The prettify-symbols-mode minor-mode (included with emacs from version 24.4 onwards) displays text in your buffer as (usually) unicode symbols that express the same thing to improve readability. A good example would be displaying the boolean operators as their unicode equivalents.

To enable the feature just add these lines to the scala-mode-hook:

(setq prettify-symbols-alist scala-prettify-symbols-alist)
(prettify-symbols-mode)

Also feel free to customise the prettify rules by adding or removing from the scala-prettify-symbols-alist alist.

Libre fonts that seems to work well with this feature are:

emacs-scala-mode's People

Contributors

4lex1v avatar ancane avatar andreas-roehler avatar bmalehorn avatar colonelpanic8 avatar corruptmemory avatar fommil avatar gpampara avatar hgiddens avatar http-418 avatar hvesalai avatar isomarcte avatar jeberger avatar jilen avatar jjl avatar kazark avatar kpbochenek avatar kurnevsky avatar mgttlinger avatar nicferrier avatar nloyola avatar non avatar reactormonk avatar sethtisue avatar swsnr avatar toxaris avatar vlachjosef avatar zbskii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

emacs-scala-mode's Issues

Colouring of setters

In
def foo_=(aFoo: String) =

the string foo_= should be in function face. Is not because = as a reserved character is coloured before functions and function face does not override.

case statements inhibit escape char highlighting

Certain constructions seem to disable highlighting of escaped chars:

case '' => sb.append("\")
case '\b' => sb.append("\b")
case '\f' => sb.append("\f")

whereas lines like the following work:

val s = "\"
val t = "\b"
val u = "\f"

insert stars when writing comments

  /* if I am writing a comment and I type newline
  I end up here.

what I'd really like to happen is

  /* if I am writing a comment and I type newline
   * I end up here.

(note asterisk)

and for scaladoc comments, it should take note of which style I am using: Java vs short Scala.

Bad indentation defaults

I was very surprised by the default indentation. I'm pretty confident that this is what most people would expect to see:

(setq scala-indent:indent-value-expression nil)
(setq scala-indent:align-parameters nil)
(setq scala-indent:align-forms nil)

The mode becomes awesome after those changes.

Indenting of lambdas

map ( foo => {
        here
     }
)

Looks ugly. Would like it to be

map ( foo => {
  here
})

Missing \\ escapes

Currently it seems like the escape sequence \ is missed.

This causes problems in strings that contain this sequence.

Numbers incorrectly highlighting inside barewords

Right now if you write something like:

bar22.foo

You'll see "22.f" highlighted as a number, which is wrong.

I fixed this by highlighting all barewords (i.e. symbolic or alpha identifiers not detected as a type or keyword) with a default font-fact, thereby preventing them from being highlighted another way.

[Highlight] Identifier following right associative operator treated as type annotation

I think i discovered a bug in syntax highlighting. When we have a right associative operator followed by any identifier, this very identifier is colored in the same way a type annotation is. Take this example:

a :: b :: Nil

Here a is colored as expected, but b is colored as a type annotation.
When we use literals this problem does not occur:

1 :: 2 :: Nil

This highlights just fine.

Regards Alex

Invalid function: scala-mode-map:define-keys

Hello all,

I've installed scala-mode2 from melpa. I'm using the new emacs24.2.93.

This is what I've added to my .emacs to make scala-mode2 work:

(when (not (package-installed-p 'scala-mode2))
  (package-install 'scala-mode2))
(require 'scala-mode2)

This is what I get when opening emacs:

´´´
Invalid function: scala-mode-map:define-keys
´´´

ideas?

Cheers!
A.

strange indentation of closure body

    def combineRestrictions(usableBy1: String, usableBy2: String): String =
      usableBy1.map(c => if(c != '-' && usableBy2.indexOf(c) != -1) c
                      else '-')

you can kind of see where it's coming from, but it's not optimal

Autopair doesn't insert matching " when in scala-mode2

Hello,

I'm not sure what causes this, but autopair doesn't insert the matching " when in scala-mode2. I cannot reproduce this error in scala-mode or any other major mode in emacs; however, it inserts the corresponding parenthesis, brackets, etc. I'm guessing this is more an issue of scala-mode2 than autopair, but I'm not really sure.

Invert class parameter indentation

As mentioned in the docs the parameter indentation is exactly opposite that of the style guide. I recommend changing it or at least providing an option to modify the behavior.

I can open a pull request if you are open to such a change.

indentation error

If you start a new buffer, and input:

class Foo[A] {

then when you hit newline and tab, you get an error. If you hit newline twice, then go up and hit tab it's fine. The error seems to occur when there's no next line beyond the current one.

Shebangs cause entire text to highlight as comment

With a shebang present, scala-mode2 highlights the entire file as one big comment.

Example:

$ cat Hello.scala 
#!/usr/bin/env scala

object Hello {
  def main(args: Array[String]) {
    println("Hello World!")
  }
}

Comments should use the same face.

Currently it seems like scaladoc comments highlight differently from normal comments. I am finding this really distracting, and it doesn't seem like expected behavior.

Should this be a setting? Are there other mods that make this kind of distinction? Should I just learn to deal with it?

keywords supercede symbols

Currently, symbols like 'true and 'null are highlighted differently from symbols like 'foo and 'bar. This is incorrect, since these are all symbols.

Scala mode doesn't ignore /* in ``

implicit val AssetUploadAndMetadataUnmarshaller = Unmarshaller[AssetUploadAndMetadata](ContentTypeRange(MediaRanges.`multipart/*`)){
  * case(HttpEntity.NonEmpty(contentType, data)) => "aaarg!"
}

Note that multipart/* is inside backticks. scala-mode-2 considers that to be the start of a comment, and C-M inserts a * at the beginning of the new line. Additionally, if I fix that and remove the hanging *, the indentation screws up:

implicit val AssetUploadAndMetadataUnmarshaller = Unmarshaller[AssetUploadAndMetadata](ContentTypeRange(MediaRanges.`multipart/*`)){
    case(HttpEntity.NonEmpty(contentType, data)) =>
    * "aaargh"

I think the culpable regex for the coloring is here: https://github.com/hvesalai/scala-mode2/blob/master/scala-mode2-fontlock.el#L489

But I am not sure. I will try adding a "not `" on the regex and make a pull request if that fixes it. I assume that something similar will be found for indentation.

String interpolation support

The fontlock branch now has a first attempt at string interpolation. It still requires string-propertise functions to be rewritten to understand nested strings inside ${}.

"Foo ${ "This isn't supported now" } Zot"

(Seems that github comment formatter doesn't either support string interpolation)

`if` bodies aren't always indented

examples:

      if(r.isInstanceOf[_task])
      app.args.head.accept(new AgentTypeCheckerVisitor(currentProcedure, "OTPL"))
      else if(r.syntax.blockAgentClassString != null)
        chooseVisitorAndContinue(r.syntax.blockAgentClassString, app.args)
      else
        super.visitReporterApp(app)
          try {
            if(java.lang.Boolean.getBoolean("org.nlogo.lang.requireSingularBreedArgument"))
            cAssert(breedList.size == 2,
                    "breed requires a singular form since org.nlogo.lang.requireSingularBreedArgument is true",
                    token)
          }

Key words in triple quote might cause very high cpu usage, in some condition

Run emacs with -Q option, then eval below two line to add scala-mode2 support:

 ;; I put scala-mode2 related files here
(add-to-list 'load-path "~/emacs/site-lisp")
(require 'scala-mode2)

Then load a scala file with below content:

class A {
  def b() = {
    Seq("""package ${pkg}
import x.y.z
class ${cls} extends E with F {

""")

    Seq("x", "/" + "a.b".("\\.").mkString("/") + ".c")

    Seq("z", "")
  }

  def c() = {
    Seq("a", "b", "c", "d" + "/" + "e")
  }
}

Then, goto line 6(just below "class ${cls}"), and type "val ", then emacs will hang, and the cpu usage goes to 100%.

Or more simple, load a scala file with below content, will trigger the problem:

class A {
  def b() = {
    Seq("""package ${pkg}
import x.y.z
class ${cls} extends E with F {
val 
""")

    Seq("x", "/" + "a.b".("\\.").mkString("/") + ".c")

    Seq("z", "")
  }

  def c() = {
    Seq("a", "b", "c", "d" + "/" + "e")
  }
}

PS: emacs version is 24.3.1, and scala-mode2 rev is c9dd697(though not last one, but *.el files not change during last several commits).

Regression in pattern1 highlight

var x, y: String = zot

y used to work, now we get error:

Error during redisplay: (jit-lock-function 108) signaled (error "No match 1 in highlight (1 scala-font-lock:var-face t)")

Weird indenting in certain cases

Currently, we get the following indentation:

def foo7(x: Int) = if (x > 10)
                     123
                   else
                     999

This should probably be treated the same way it would if it had braces.

scalariform syncronisation

It would be awesome to have an sbt plugin (or standalone app) that outputs the closest scala-mode2 configuration that matches the project's scalariform settings.

100% CPU with triple-quoting

Opening a scala file with the following content causes Emacs to run at 100% cpu for a very long time (I gave up waiting after 5 minutes). If I C-g to cancel the mode run the quoting is highlighted incorrectly.

Thanks,

Derek

Content:

package foo.bar

import org.specs2.mutable.Specification

class FullCpuSpec extends Specification {
  "foo" should {
    "Sloops lagrange" in {
      val inputs = """[
{ "foo" : "1234", "bar" : "baz blarg", "bazs" : [   "1234", "1234"] },
{ "foo" : "12345678", "bar" : "blergh", "bazs" : [  "1234", "1234"] },
{ "foo" : "12345678", "bar" : "blergh", "bazs" : [  "1234", "1234"] },
{ "foo" : "12345678", "bar" : "blergh", "bazs" : [  "1234", "1234"] },
{ "foo" : "12345678", "bazs" : [ "1234", "1234"] }
]"""
    }
  }
}

beginning-of-defun, end-of-defun & mark-defun don't work

These commands (C-M-a, C-M-e, C-M-h) don't seem to function at all in scala-mode2; however, these are highly productive commands when moving around and operating on source code; would it be realistic to hope that one day scala-mode2 will support these functions? I've verified that at least c-mode, c++-mode,python-modeandlisp-mode` support these functions, so most probably this is standard and can be expected by users to be available in scala-mode2 as well.

P.S. I'm aware of C-c C-v . as an alternative to mark-defun, but it's not really equivalent in speed.

Autoindentation fails when optional braces are omitted

Scala code often uses braces ({}) to denote object bodies, which scala-mode2 correctly indents. Pressing TAB for autoindentation on any line of Hello.scala results in this correctly indented code:

https://gist.github.com/mcandre/af909a109621606d0afb

However, Scala allows omitting braces for some body types, such as object bodies:

https://gist.github.com/mcandre/ea4f80033536e8036fb1

When braces are omitted, scala-mode2 mistakenly dedents the line:

https://gist.github.com/mcandre/32fa50ff0da2552c547c

Please fix this by allowing either a newline or curly brace to signify such bodies.

`if` + `else` misaligned inside parens

so e.g.

    val newOwns = parseVarList(
        if (isLinkBreed) AgentKind.Link
          else AgentKind.Turtle)

outside of parens the if and else would be indented the same

incorrect highlighting after ::

so e.g. in def foo = 0 :: bar bar ends up green, as if it were a type, when it should just be black.

same for :::, #::, #:::

screen shot

forward/backward word specialised for scala

It would be great if alt-{left,right} had special behaviour in scala files, e.g. camel case words are respected, differentiating between variables and operators ("this+that" will be skipped entirely as a single word by default behaviour), etc

case and if don't mix

case 0 => if (network.maskBits < n.maskBits)
  asd
else
  asfd

asd, else and asfd should be one step right

Indenting class parameters

Is there a customization I can make to change the following default behavior:

class ClassWithLotsOfFields(
  val field1: String,
    val field2: String,
      val field3: String,
        val field4: String
)

Specifically, I would like to align those parameter declarations with the initial parameter (field1).

MELPA package

Would be cool if we added scala-mode2 to the melpa repo? Would be nice to be able to update (for users) from within Emacs itself.

Don't mind doing it but I thought I'd create an issue just to make it visible

If body in parameter lists

the anchor for if body is not calculated correctly in parameter lists.

        return new VPLeaf(nextEntries, if (pendingChanged)
                            filteredPending
                                       else
                            pending)

if should not force expression start

The following does not indent correctly

n.key.get(point).iterator ++
if (n.key.center < point)

if should be indented one step since it is run-on

Special cases for add-space-for-scaladoc-asterisk

I use the default setting of scala-indent:add-space-for-scaladoc-asterisk to t, so when I press RET * in a ScalaDoc comment, a space is inserted automatically. This is great except for two situations:

  1. I press RET RET to add an empty line in a Scaladoc comment. In this case, I get something like " * \n" for the empty line, but I would prefer something like " *\n" without the trailing whitespace.
  2. I press RET * / RET to end the Scaladoc comment. In this case, I get something like " * /\n" for the intended last line of the comment, but I really need something like " */\n" to actually end the comment.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.