Skip to content

Instantly share code, notes, and snippets.

@nimeshneema
Last active March 27, 2026 07:19
Show Gist options
  • Select an option

  • Save nimeshneema/90726309fe6aff6219fd29cb726beb37 to your computer and use it in GitHub Desktop.

Select an option

Save nimeshneema/90726309fe6aff6219fd29cb726beb37 to your computer and use it in GitHub Desktop.

Emacs Scala IDE with Metals

Install Emacs 30.2

  • Update system packages:

    sudo apt update && sudo apt upgrade -y

  • Install the essential tools:

    sudo apt install -y curl git unzip software-properties-common

  • Add the Emacs PPA:

    sudo add-apt-repository -y ppa:ubuntuhandbook1/emacs

  • Update with new PPA:

    sudo apt update

  • Install Emacs:

    sudo apt install -y emacs-pgtk

  • Verify installation:

    emacs --version


Install Java

  • Install Java 17 (OpenJDK):

    sudo apt install -y openjdk-17-jdk openjdk-17-source

  • Verify installation:

    java -version

  • Set JAVA_HOME persistently:

    echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-$(dpkg --print-architecture)' >> ~/.bashrc

    source ~/.bashrc

  • Verify that the environment variable is setup:

    echo $JAVA_HOME

    ls $JAVA_HOME/bin/java


Install Scala Toolchain & Coursier

  • Check the hardware architecture (whether x86_64 or aarch64 (ARM 64)):

    uname -a

  • Download the appropriate version of the tool keeping the correct architecture in mind:

    • Download command for x86_64:

      curl -fL "https://github.com/coursier/launchers/raw/master/cs-x86_64-pc-linux.gz" | gzip -d > cs

    • Download command for aarch64:

      curl -fL "https://github.com/VirtusLab/coursier-m1/releases/latest/download/cs-aarch64-pc-linux.gz" | gzip -d > cs

  • Make cs executable:

    chmod u+x cs

  • Run Scala setup (installs cs, scala-cli, sbt, scalafmt, etc.):

    ./cs setup -y

  • Source updated PATH:

    source ~/.profile

  • Verify installation:

    cs version

    sbt --version

  • Perform cleanup:

    rm ./cs


Install Metals via Coursier

  • Install Metals:

    cs install metals

  • Verify installation:

    metals --version

    which metals

    The last command should print: ~/.local/share/coursier/bin/metals


Configure Emacs for Scala IDE

  • Create the Emacs config (if it doesn't exist):

    mkdir ~/.emacs.d

  • Create the config file:

    touch ~/.emacs.d/init.el

  • Downalod the ~/.emacs.d/init.el file using the link:

    https://gist.githubusercontent.com/nimeshneema/9060117c2d94c8912176a5b74a127383/raw/b8ee41dd8d2992abb695e80f9922d0332ce19ad5/init.el


First Launch — Package Installation

  • On first launch, Emacs connects to the MELPA and downloads all packages. This may take 1-3 minutes. You'll see activity in the Emacs minibuffer. When it settles, quit emacs and re-launch.

  • Verify packages are installed:

    Press M-x, type package-list-packages, and press RET. This will list all the packages.

    Type /s enter installed press RET to see the installed packages.

    Type /s enter dependency press RET to see the dependencies.

  • Confirm the following packages all appear labelled either as "installed" or "dependency":

    scala-mode

    lsp-mode

    lsp-metals

    lsp-ui

    company

    flycheck

    yasnippet

    sbt-mode

    dap-mode


Create a Test Project & Verify Everything Works

  • Download a minimal sample Scala project using the link:

    https://github.com/nimeshneema/scala-test-project/archive/main.zip

    Once downloaded, unzip and move the scala-test-project to home directory.


Pre-compile with sbt (separate from Emacs to isolate issues)

  • Run the following:

    cd ~/scala-test-project

    sbt compile

    First run downloads sbt + Scala + deps — may take several minutes

    Expected output: [success]

  • Open in Emacs

    cd ~/scala-test-project

    emacs src/main/scala/example/Main.scala


IDE Feature Verification Checklist

  • Test each feature once the build import has completed:

    1. Syntax Highlighting

      Keywords, strings, comments should each be in distinct colors.

    2. Error Diagnostics

      Type val x: Int = "oops" on a new line, save (C-x C-s), wait a few seconds. An error should appear (underline/highlight + sideline message). Undo with C-/.

    3. Auto-Completion

      Type fleet. on a new line inside main. A popup should appear showing filter, map, head, length, etc. Navigate with arrows, accept with RET, cancel with C-g.

    4. Hover Documentation

      Cursor on filterC-c C-d (or M-x lsp-ui-doc-show). Type signature and docs should appear.

    5. Go to Definition

      Cursor on checkGear in the call → M-. (Meta-period). Jumps to the definition. M-, jumps back.

    6. Find References

      Cursor on AircraftM-x lsp-find-references RET. Lists all usages.

    7. Type at Point

      Cursor on retractableGearC-c C-t. Should show List[Aircraft].

    8. Code Actions

      C-c C-a at various positions to see available actions.

    9. Rename Symbol

      Cursor on fleetC-c C-r → type aircraftFleet → RET. All occurrences rename. Undo with C-/ repeated.

    10. Format Buffer

      C-c C-f reformats per Scalafmt rules.

    11. Organize Imports

      Add import scala.collection.mutable.ListBuffer at top (unused). C-c C-o should remove it.

    12. Code Lenses

      Look above def main for clickable annotation like ▶ run.

    13. Build Import on Change

      Open build.sbt (C-x C-f build.sbt), add a comment, save. Should prompt to re-import.

    14. sbt Mode

      M-x sbt-start RET → type compile in the sbt shell → run to execute. Switch back with C-x b Main.scala RET.

    15. Metals Doctor

    M-x lsp-metals-doctor-run RET. Diagnostic report should appear.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment