clojure-lsp / clojure-lsp

Clojure & ClojureScript Language Server (LSP) implementation

Home Page:https://clojure-lsp.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Creating a new Clojure file with æ/ø/å in the filename breaks `workspace/willRenameFiles`

magnars opened this issue · comments

Describe the bug

Saving a new file with characters from a non-US alphabet will throw an "Internal Error", in Emacs preventing the buffer from being marked as saved. The current workaround I have found is to save the file in fundamental-mode. Once it exists, lsp no longer throws.

To Reproduce

  1. Create a new file in an lsp-enabled Clojure project, call it something quirky, like kåre.clj
  2. Try saving the file.
  3. See "Internal Error"

Expected behavior

I was hoping to save my file without workarounds. 😅

User details:

  • OS: Emacs on MacOS

  • Version:

    clojure-lsp 2024.04.22-11.58.08-nightly
    clj-kondo 2024.03.13

Additional context

Toggling on debug-on-error in Emacs shows this stack:

Debugger entered--Lisp error: (error "Internal error")
  signal(error ("Internal error"))
  error("Internal error")
  lsp-request("workspace/willRenameFiles" #<hash-table equal 1/65 0x47ec724d>)
  lsp--on-rename-file(#<subr rename-file> "/Users/magnars/work/parenteser/src/parenteser/kåre..." "/Users/magnars/.emacs.d/backups/!Users!magnars!wor..." t)
  apply(lsp--on-rename-file #<subr rename-file> ("/Users/magnars/work/parenteser/src/parenteser/kåre..." "/Users/magnars/.emacs.d/backups/!Users!magnars!wor..." t))
  rename-file("/Users/magnars/work/parenteser/src/parenteser/kåre..." "/Users/magnars/.emacs.d/backups/!Users!magnars!wor..." t)
  backup-buffer()
  basic-save-buffer-2()
  basic-save-buffer-1()
  basic-save-buffer(t)
  save-buffer(1)
  funcall-interactively(save-buffer 1)
  call-interactively(save-buffer nil nil)
  command-execute(save-buffer)

Looking at the stack trace, here's what happens:

  • Emacs keeps a backup of the file somewhere while it is unsaved.
  • When saving, it triggers a rename-file which in turn triggers the lsp-mode rename-file hook
  • This performs the workspace/willRenameFiles

This works as expected with regular characters, but breaks with æ/ø/å and presumably other non-US alphabet chars.

So, the problem is actually renaming files with strange chars. Due to the way Emacs handles new files, this leaks into saving any new files with strange chars.

Having tried (naively) to reproduce it it clojure-lsp's test suite, it might come down to this:

(shared/uri->filename "file:///user/project/src/my/kåre.clj")

1. Unhandled java.lang.IllegalArgumentException
   Bad escape

         UnixUriUtils.java:   88  sun.nio.fs.UnixUriUtils/fromUri
UnixFileSystemProvider.java:  125  sun.nio.fs.UnixFileSystemProvider/getPath
                 Path.java:  204  java.nio.file.Path/of
                Paths.java:   98  java.nio.file.Paths/get
                shared.clj:  179  clojure-lsp.shared/uri-obj->filepath
                shared.clj:  177  clojure-lsp.shared/uri-obj->filepath
                shared.clj:  223  clojure-lsp.shared/uri->filename
                shared.clj:  202  clojure-lsp.shared/uri->filename
                      REPL:  349  clojure-lsp.feature.file-management-test/eval60866

I'm not sure if this is me missing a step on the way where maybe the "Bad escape" would be fixed, tho.