emacs-lsp / lsp-metals

lsp-mode :heart: metals
https://emacs-lsp.github.io/lsp-metals
GNU General Public License v3.0
58 stars 34 forks source link

Tab does not indent #103

Closed udalrich closed 8 months ago

udalrich commented 8 months ago

Describe the bug I attempted to use the configuration at https://scalameta.org/metals/docs/editors/emacs as the full contents of my .emacs. When I open a scala file, it asked my which server I wanted to import, and I said to use metals. I imported the project from the root of the project. If I have code like

     val rootActor = foo()
^

with the cursor at the ^ and type TAB, the cursor remains at the same place and does not indent.

If I then edit the file to contain

     val rootActor = foo()
^rootActor

The cursor is again at ^. Pressing TAB does not indent. I also get a message in *Messages*: yas-next-field: Wrong type argument: overlayp, nil To Reproduce

# Clean up anything previous.  Start in project root.
rm -r .metals ~/.emacs.d/.cask/var/lsp/server/metals/
emacs build.sbt

Emacs asks how to import the project. Type . (Import project at current directory, which is the directory with build.sbt.)

Emacs asks if it should import the build in the new workspace. Type Import build RET

Open (using C-x C-f) Main.scala.

Go to the blank line at the bottom of the file, with the cursor at the start of the line. Press TAB.
Type rootActor C-a to enter text and go back to the beginning of the line. Press TAB

Expected behavior Pressing TAB should indent the line appropriately

Files ~/.emacs

;; Hack to work around errors about svg files
(when (= emacs-major-version 28)
         (add-to-list 'image-types 'svg))

(require 'package)

;; Add melpa to your packages repositories
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)

(package-initialize)

;; Install use-package if not already installed
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(require 'use-package)

;; Enable defer and ensure by default for use-package
;; Keep auto-save/backup files separate from source code:  https://github.com/scalameta/metals/issues/1027
(setq use-package-always-defer t
      use-package-always-ensure t
      backup-directory-alist `((".*" . ,temporary-file-directory))
      auto-save-file-name-transforms `((".*" ,temporary-file-directory t)))

;; Enable scala-mode for highlighting, indentation and motion commands
(use-package scala-mode
  :interpreter ("scala" . scala-mode))

;; Enable sbt mode for executing sbt commands
(use-package sbt-mode
  :commands sbt-start sbt-command
  :config
  ;; WORKAROUND: https://github.com/ensime/emacs-sbt-mode/issues/31
  ;; allows using SPACE when in the minibuffer
  (substitute-key-definition
   'minibuffer-complete-word
   'self-insert-command
   minibuffer-local-completion-map)
   ;; sbt-supershell kills sbt-mode:  https://github.com/hvesalai/emacs-sbt-mode/issues/152
   (setq sbt:program-options '("-Dsbt.supershell=false")))

;; Enable nice rendering of diagnostics like compile errors.
(use-package flycheck
  :init (global-flycheck-mode))

(use-package lsp-mode
  ;; Optional - enable lsp-mode automatically in scala files
  ;; You could also swap out lsp for lsp-deffered in order to defer loading
  :hook  (scala-mode . lsp)
         (lsp-mode . lsp-lens-mode)
  :config
  ;; Uncomment following section if you would like to tune lsp-mode performance according to
  ;; https://emacs-lsp.github.io/lsp-mode/page/performance/
  ;; (setq gc-cons-threshold 100000000) ;; 100mb
  ;; (setq read-process-output-max (* 1024 1024)) ;; 1mb
  ;; (setq lsp-idle-delay 0.500)
  ;; (setq lsp-log-io nil)
  ;; (setq lsp-completion-provider :capf)
  (setq lsp-prefer-flymake nil)
  ;; Makes LSP shutdown the metals server when all buffers in the project are closed.
  ;; https://emacs-lsp.github.io/lsp-mode/page/settings/mode/#lsp-keep-workspace-alive
  (setq lsp-keep-workspace-alive nil))

;; Add metals backend for lsp-mode
(use-package lsp-metals)

;; Enable nice rendering of documentation on hover
;;   Warning: on some systems this package can reduce your emacs responsiveness significally.
;;   (See: https://emacs-lsp.github.io/lsp-mode/page/performance/)
;;   In that case you have to not only disable this but also remove from the packages since
;;   lsp-mode can activate it automatically.
(use-package lsp-ui)

;; lsp-mode supports snippets, but in order for them to work you need to use yasnippet
;; If you don't want to use snippets set lsp-enable-snippet to nil in your lsp-mode settings
;; to avoid odd behavior with snippets and indentation
(use-package yasnippet)

;; Use company-capf as a completion provider.
;;
;; To Company-lsp users:
;;   Company-lsp is no longer maintained and has been removed from MELPA.
;;   Please migrate to company-capf.
(use-package company
  :hook (scala-mode . company-mode)
  :config
  (setq lsp-completion-provider :capf))

;; Posframe is a pop-up tool that must be manually installed for dap-mode
(use-package posframe)

;; Use the Debug Adapter Protocol for running tests and debugging
(use-package dap-mode
  :hook
  (lsp-mode . dap-mode)
  (lsp-mode . dap-ui-mode))

build.sbt

// Project Config Values
val ProjectName    = "lsp-metals-bug-example"
val ProjectVersion = "2.14.0-SNAPSHOT"
val Scala3Version  = "3.3.1"

// Other Dependency Values
val AkkaCoreVersion         = "2.6.21" // Keep at 2.6.x

ThisBuild / scalaVersion := Scala3Version
ThisBuild / organization := "com.example.lsp.metals"
Compile / run / fork     := true
Compile / unmanagedResourceDirectories += baseDirectory.value / "conf"
Test / parallelExecution := false

scalacOptions ++= Seq(
  "-unchecked",      // Warn on unchecked assumption
  "-deprecation",    // Warn on deprecated method use
  "-feature",        // Warn on features that should be imported explicitly
  "-Xfatal-warnings" // Flag warnings as fatal errors (including above)
)
scalacOptions ++= Seq("-java-output-version", "17") // Compile to Java 17

lazy val root = project
  .in(file("."))
  .settings(
    name                                 := ProjectName,
    version                              := ProjectVersion,
    // Project Dependencies
    libraryDependencies ++= Seq(
      "com.typesafe.akka"             %% "akka-actor-typed"                  % AkkaCoreVersion,
      "com.typesafe.akka"             %% "akka-actor-testkit-typed"          % AkkaCoreVersion,
    ),
    // Some libraries have incompatible transitive dependencies, especially when cross-compiling Scala 2.13 and 3
    // Exclude incompatible libaries below
    excludeDependencies ++= Seq(
      "com.typesafe.akka"            % "akka-actor_2.13",
      "org.scala-lang.modules"       % "scala-java8-compat_2.13",
      "com.fasterxml.jackson.module" % "jackson-module-scala_2.13"
    ),
  )

src/main/scala/com/example/lsp/metals/Main.scala

package com.example.lsp.metals

import akka.actor.typed.ActorSystem
import akka.japi.pf.UnitMatch

class RootActor:
  def buildBehavior: Int =
    val x = 3
    x * 2

object Main:

  def run(args: List[String]): Unit =
    val rootActor = new RootActor()

Screenshots

Logs Please include the debug stack trace (if there is an error) and the content of Messages buffer with lsp-print-io set to t in case the bug is related to client->server communication.

*Backtrace with debug-on-error set to t after pressing TAB at the start of the line

Debugger entered--Lisp error: (wrong-type-argument overlayp nil)
  overlay-get(nil yas--field)
  yas-next-field()
  yas-next-field-or-maybe-expand()
  funcall-interactively(yas-next-field-or-maybe-expand)
  call-interactively(yas-next-field-or-maybe-expand nil nil)
  command-execute(yas-next-field-or-maybe-expand)

*Messages*

For information about GNU Emacs and the GNU system, type C-h C-a.
LSP :: Connected to [metals:47650/starting /Users/me/test/lsp-metals].
LSP :: metals:47650 initialized successfully in folders: (/Users/me/test/lsp-metals)
LSP :: Connected to [metals:47650 /Users/me/test/lsp-metals].
<Messages about saving Main.scala>
yas-next-field: Wrong type argument: overlayp, nil [2 times]

Version: GNU Emacs 28.2 (build 1, x86_64-apple-darwin18.7.0, NS appkit-1671.60 Version 10.14.6 (Build 18G95)) of 2023-02-22

*lsp-log*

Command "/Users/me/.emacs.d/.cache/lsp/metals/metals" is present on the path.
Command "semgrep lsp" is not present on the path.
Command "/Users/me/.emacs.d/.cache/lsp/metals/metals" is present on the path.
Command "semgrep lsp" is not present on the path.
Found the following clients for /Users/me/test/lsp-metals/build.sbt: (server-id metals, priority -1)
The following clients were selected based on priority: (server-id metals, priority -1)
2023.10.10 12:03:49 INFO  logging to files /Users/me/test/lsp-metals/.metals/metals.log
2023.10.10 12:03:49 INFO  Started: Metals version 1.0.1 in folders '/Users/me/test/lsp-metals' for client emacs GNU Emacs 28.2 (build 1, x86_64-apple-darwin18.7.0, NS appkit-1671.60 Version 10.14.6 (Build 18G95))
 of 2023-02-22.
2023.10.10 12:03:50 INFO  time: initialize in 0.55s
Creating watchers for following 12 folders:
  /Users/me/test/lsp-metals
  /Users/me/test/lsp-metals/.bsp
  /Users/me/test/lsp-metals/project
  /Users/me/test/lsp-metals/project/project
  /Users/me/test/lsp-metals/project/project/project
  /Users/me/test/lsp-metals/src
  /Users/me/test/lsp-metals/src/main
  /Users/me/test/lsp-metals/src/main/scala
  /Users/me/test/lsp-metals/src/main/scala/com
  /Users/me/test/lsp-metals/src/main/scala/com/example
  /Users/me/test/lsp-metals/src/main/scala/com/example/lsp
  /Users/me/test/lsp-metals/src/main/scala/com/example/lsp/metals
2023.10.10 12:03:52 INFO  no build target found for /Users/me/test/lsp-metals/build.sbt. Using presentation compiler with project's scala-library version: 3.2.0
2023.10.10 12:03:53 INFO  Attempting to connect to the build server...
2023.10.10 12:03:53 INFO  Bloop uses /Users/me/.jenv/versions/17.0 defined at /Users/me/.bloop/bloop.json
2023.10.10 12:03:53 INFO  skipping build import with status 'Installed'
2023.10.10 12:03:53 INFO  tracing is disabled for protocol BSP, to enable tracing of incoming and outgoing JSON messages create an empty file at /Users/me/test/lsp-metals/.metals/bsp.trace.json or /Users/me/Library/Caches/org.scalameta.metals/bsp.trace.json
2023.10.10 12:03:53 INFO  Attempting to connect to the build server...
2023.10.10 12:03:53 INFO  Bloop uses /Users/me/.jenv/versions/17.0 defined at /Users/me/.bloop/bloop.json
2023.10.10 12:03:53 INFO  tracing is disabled for protocol BSP, to enable tracing of incoming and outgoing JSON messages create an empty file at /Users/me/test/lsp-metals/project/.metals/bsp.trace.json or /Users/me/Library/Caches/org.scalameta.metals/bsp.trace.json
2023.10.10 12:03:53 INFO  time: Connected to build server in 0.82s
2023.10.10 12:03:53 INFO  Connected to Build server: Bloop v1.5.8
2023.10.10 12:03:54 INFO  time: code lens generation in 3.85s
2023.10.10 12:03:55 INFO  no build target found for /Users/me/test/lsp-metals/build.sbt. Using presentation compiler with project's scala-library version: 3.2.0
2023.10.10 12:03:55 INFO  time: code lens generation in 2.91s
2023.10.10 12:03:55 INFO  time: code lens generation in 5.56s
2023.10.10 12:03:55 INFO  time: code lens generation in 2.91s
2023.10.10 12:03:56 INFO  time: indexed workspace in 2.75s
Command "/Users/me/.emacs.d/.cache/lsp/metals/metals" is present on the path.
Command "semgrep lsp" is not present on the path.
Command "/Users/me/.emacs.d/.cache/lsp/metals/metals" is present on the path.
Command "semgrep lsp" is not present on the path.
Found the following clients for /Users/me/test/lsp-metals/src/main/scala/com/example/lsp/metals/Main.scala: (server-id metals, priority -1)
The following clients were selected based on priority: (server-id metals, priority -1)
2023.10.10 12:04:02 INFO  compiling root (1 scala source)
2023.10.10 12:04:02 INFO  time: compiled root in 0.23s
2023.10.10 12:04:07 ERROR Error encountered during file watching
java.nio.file.NoSuchFileException: /Users/me/test/lsp-metals/src/main/scala/com/example/lsp/metals/.#Main.scala
    at sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
    at sun.nio.fs.UnixPath.toRealPath(UnixPath.java:825)
    at com.swoval.files.SymlinkWatcher.addSymlink(SymlinkWatcher.java:194)
    at com.swoval.files.SymlinkFollowingPathWatcher$1.onNext(SymlinkFollowingPathWatcher.java:48)
    at com.swoval.files.SymlinkFollowingPathWatcher$1.onNext(SymlinkFollowingPathWatcher.java:36)
    at com.swoval.files.Observers.onNext(Observers.java:31)
    at com.swoval.files.ApplePathWatcher$1.accept(ApplePathWatcher.java:287)
    at com.swoval.files.ApplePathWatcher$1.accept(ApplePathWatcher.java:261)
    at com.swoval.files.apple.FileEventMonitorImpl$WrappedConsumer$1.run(FileEventMonitors.java:178)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.lang.Thread.run(Thread.java:833)

2023.10.10 12:04:11 INFO  compiling root (1 scala source)
2023.10.10 12:04:11 INFO  time: compiled root in 0.7s
2023.10.10 12:04:38 ERROR Error encountered during file watching
java.nio.file.NoSuchFileException: /Users/me/test/lsp-metals/src/main/scala/com/example/lsp/metals/.#Main.scala
    at sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
    at sun.nio.fs.UnixPath.toRealPath(UnixPath.java:825)
    at com.swoval.files.SymlinkWatcher.addSymlink(SymlinkWatcher.java:194)
    at com.swoval.files.SymlinkFollowingPathWatcher$1.onNext(SymlinkFollowingPathWatcher.java:48)
    at com.swoval.files.SymlinkFollowingPathWatcher$1.onNext(SymlinkFollowingPathWatcher.java:36)
    at com.swoval.files.Observers.onNext(Observers.java:31)
    at com.swoval.files.ApplePathWatcher$1.accept(ApplePathWatcher.java:287)
    at com.swoval.files.ApplePathWatcher$1.accept(ApplePathWatcher.java:261)
    at com.swoval.files.apple.FileEventMonitorImpl$WrappedConsumer$1.run(FileEventMonitors.java:178)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.lang.Thread.run(Thread.java:833)

Cancelling textDocument/codeAction(104) in hook after-change-functions
Cancelling textDocument/codeLens(108) in hook after-change-functions
Cancelling textDocument/codeAction(107) in hook after-change-functions
2023.10.10 12:07:10 ERROR Error encountered during file watching
java.nio.file.NoSuchFileException: /Users/me/test/lsp-metals/src/main/scala/com/example/lsp/metals/.#Main.scala
    at sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
    at sun.nio.fs.UnixPath.toRealPath(UnixPath.java:825)
    at com.swoval.files.SymlinkWatcher.addSymlink(SymlinkWatcher.java:194)
    at com.swoval.files.SymlinkFollowingPathWatcher$1.onNext(SymlinkFollowingPathWatcher.java:48)
    at com.swoval.files.SymlinkFollowingPathWatcher$1.onNext(SymlinkFollowingPathWatcher.java:36)
    at com.swoval.files.Observers.onNext(Observers.java:31)
    at com.swoval.files.ApplePathWatcher$1.accept(ApplePathWatcher.java:287)
    at com.swoval.files.ApplePathWatcher$1.accept(ApplePathWatcher.java:261)
    at com.swoval.files.apple.FileEventMonitorImpl$WrappedConsumer$1.run(FileEventMonitors.java:178)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.lang.Thread.run(Thread.java:833)

Cancelling textDocument/codeAction(210) in hook post-command-hook
kurnevsky commented 8 months ago

Check the readme about metals.allow-multiline-string-formatting=off.