sublimelsp/LSP-elixir

lsp_format_on_save does nothing

rpbaptist opened this issue · 16 comments

I have the following in my Elixir.sublime_settings:

{
  "lsp_format_on_save": true,
  "only_show_lsp_completions": true,
}

When I save a file, the formatter does not run (or silently fails?). When I use the command panel to run "LSP: Format file" everything is in order and the file is formatted as expected.

Output from LSP troubleshoot:

Troubleshooting: lsp-elixir

Version

  • LSP: 1.12.1
  • Sublime Text: 4113

Server Test Run

  • exit code: 0
  • output

Server Configuration

  • command
[
  "$server_path"
]
  • shell command
"/Users/richard/Library/Caches/Sublime Text/Package Storage/LSP-elixir/server/0.8.1/language_server.sh"
  • selector

  • priority_selector
(source.elixir)
  • init_options
{}
  • settings
{
  "elixirLS": {
    "dialyzerEnabled": true, 
    "dialyzerFormat": "dialyxir_long", 
    "dialyzerWarnOpts": [], 
    "fetchDeps": true, 
    "mixEnv": "test", 
    "mixTarget": null, 
    "projectDir": null
  }
}
  • env
{}

Active view

  • File name
/Users/richard/.../
  • Settings
{
  "auto_complete_selector": "meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc", 
  "lsp_active": null, 
  "syntax": "Packages/ElixirSyntax/syntaxes/Elixir.sublime-syntax"
}
  • base scope
source.elixir

Project / Workspace

  • folders
[
  "/Users/richard/code/remote/tiger"
]
  • is project: False

LSP configuration

{
  "clients": {
    "elixir-ls": {
      "enabled": false
    }, 
    "lsp-elixir": {
      "command": [
        "/Users/richard/.local/bin/language_server.sh"
      ], 
      "enabled": true, 
      "languageId": "elixir", 
      "scopes": [
        "source.elixir"
      ], 
      "syntaxes": [
        "Packages/Elixir/Syntaxes/Elixir.tmLanguage"
      ]
    }, 
    "ruby": {
      "command": [
        "solargraph", 
        "stdio"
      ], 
      "enabled": false, 
      "initializationOptions": {
        "diagnostics": false
      }, 
      "languageId": "ruby", 
      "scopes": [
        "source.ruby", 
        "source.ruby.rails", 
        "text.html.ruby"
      ], 
      "syntaxes": [
        "Packages/Ruby/Ruby.sublime-syntax", 
        "Packages/Rails/Ruby on Rails.sublime-syntax", 
        "Packages/Rails/HTML (Rails).sublime-syntax"
      ]
    }
  }
}

System PATH

  • /Applications/Sublime Text.app/Contents/SharedSupport/bin
  • /usr/local/bin
  • /usr/bin
  • /bin
  • /usr/sbin
  • /sbin
  • /Users/richard/.local/bin
  • /usr/local/sbin
  • /usr/local/opt/libpq/bin
  • /Users/richard/.asdf/shims
  • /usr/local/Cellar/asdf/0.8.1_1/libexec/bin
  • /Applications/Sublime Text.app/Contents/SharedSupport/bin
  • /Applications/kitty.app/Contents/MacOS
rchl commented

It might be timing out. The time limit is 2s. There is a bug in the latest released LSP version (fixed on main branch) that might cause the timeout message to not show up.

Does it take 2s or more for the "unsaved file" indicator to disappear on saving the file?

I'm not sure that is it. When I make a simple change to a small file and run the task through the command panel, it's pretty fast. Less than a second I'd say.

rchl commented

Oh, I see now. The lsp_format_on_save option is only supported in the main LSP settings file.

I just moved the setting from syntax specific to the main LSP settings file and there's no difference in behavior.

rchl commented

Does the LSP configuration section show it when troubleshooting?

Yes, it's there:

Troubleshooting: lsp-elixir

Version

  • LSP: 1.12.1
  • Sublime Text: 4121

Server Test Run

  • exit code: 0
  • output

Server Configuration

  • command
[
  "$server_path"
]
  • shell command
"/Users/richard/Library/Caches/Sublime Text/Package Storage/LSP-elixir/server/0.8.1/language_server.sh"
  • selector
(source.elixir)
  • priority_selector
(source.elixir)
  • init_options
{}
  • settings
{
  "elixirLS": {
    "dialyzerEnabled": true, 
    "dialyzerFormat": "dialyxir_long", 
    "dialyzerWarnOpts": [], 
    "fetchDeps": true, 
    "mixEnv": "test", 
    "mixTarget": null, 
    "projectDir": null
  }
}
  • env
{}

Active view

  • File name
/Users/richard/code/path/to/file.ex
  • Settings
{
  "auto_complete_selector": "meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc", 
  "lsp_active": true, 
  "syntax": "Packages/Elixir/Syntaxes/Elixir.tmLanguage"
}
  • base scope
source.elixir

Project / Workspace

  • folders
[
  "/Users/richard/code/remote/tiger"
]
  • is project: True
  • project data:
{
  "folders": [
    {
      "path": "code/remote/tiger"
    }
  ], 
  "index_exclude_patterns": [
    "openapi.json"
  ]
}

LSP configuration

{
  "clients": {
    "elixir-ls": {
      "enabled": false
    }, 
    "lsp-elixir": {
      "command": [
        "/Users/richard/.local/bin/language_server.sh"
      ], 
      "enabled": true, 
      "languageId": "elixir", 
      "scopes": [
        "source.elixir"
      ], 
      "syntaxes": [
        "Packages/Elixir/Syntaxes/Elixir.tmLanguage"
      ]
    }, 
    "ruby": {
      "command": [
        "solargraph", 
        "stdio"
      ], 
      "enabled": false, 
      "initializationOptions": {
        "diagnostics": false
      }, 
      "languageId": "ruby", 
      "scopes": [
        "source.ruby", 
        "source.ruby.rails", 
        "text.html.ruby"
      ], 
      "syntaxes": [
        "Packages/Ruby/Ruby.sublime-syntax", 
        "Packages/Rails/Ruby on Rails.sublime-syntax", 
        "Packages/Rails/HTML (Rails).sublime-syntax"
      ]
    }
  }, 
  "lsp_format_on_save": true
}

System PATH

  • /Applications/Sublime Text.app/Contents/SharedSupport/bin
  • /usr/local/bin
  • /usr/bin
  • /bin
  • /usr/sbin
  • /sbin
  • /Users/richard/.local/bin
  • /usr/local/sbin
  • /usr/local/opt/libpq/bin
  • /Users/richard/.asdf/shims
  • /usr/local/Cellar/asdf/0.8.1_1/libexec/bin
  • /Applications/Sublime Text.app/Contents/SharedSupport/bin
  • /Applications/kitty.app/Contents/MacOS

I think it's because Elixir LS requires .formatter.exs for it to work. It's not an LSP issue. I don't think it's LSP issue.

rchl commented

But the lsp_format_on_save and the LSP: Format File use the same server functionality.

Can you enable and provide server logs for when you save the file and when you format using LSP: Format File?

See log_server in https://lsp.sublimetext.io/troubleshooting/#self-help-instructions

OK interesting. When project dir is not present, elixir ls should allow no .formatter.exs

Yup let's see the logs.

Funny enough I see no log output at all, whether running the format manually or when saving:

LSP: starting ['/Users/richard/Library/Caches/Sublime Text/Package Storage/LSP-elixir/server/0.8.1/language_server.sh'] in /Users/richard/Exercism/elixir
LSP: lsp-elixir: Supported execute commands: ['spec:uXYbKkPoDF6UxHAijF-fl5bKwBgMSHoR', 'expandMacro:uXYbKkPoDF6UxHAijF-fl5bKwBgMSHoR', 'manipulatePipes:uXYbKkPoDF6UxHAijF-fl5bKwBgMSHoR']
LSP: lsp-elixir: registering capability: didChangeWatchedFilesProvider

But when I also log commands: sublime.log_commands(True)

command: lsp_format_document
command: gs_draw_status_bar
command: lsp_apply_document_edit {"changes": [[[76, 35], [77, 4], "", null]]}

When I save manually: command: save {"async": true}

I've also tried saving without async, but still no output other than command: save, so it seems the lsp_format_document action is never called.

I've also disabled other packages with hooks on the save command: GitSavvy, GitGutter.

This did give me an idea for a workaround however, I've added the command directly to my keybinding:

  { "keys": ["ctrl+s"], 
    "command": "chain", 
    "args": {
      "commands": [
        { "command": "lsp_format_document" },
        { "command": "save", "args": {"async": true} },
      ]
    }
  },

And typing this out, I had another idea. I've been working on Linux before and copied over my keybindings to the Mac I had to use for work now.

By default super+s is save, but I'm using ctrl+s. I can confirm that when saving with super+s, the LSP file formatting does work.

So it seems that action is bound to the default keybind and not the Sublime command.

But this means that autosave won't trigger the format. I have set "save_on_focus_lost": true, and since this also bypasses the keybinding, lsp_format_document won't run.

rchl commented

So you can just use lsp_save as your command. With lsp_format_on_save enabled it will take care of formatting too.

As for save_on_focus_lost, I don't think I have any solution for that.

rchl commented

To hook into native save and make it work for save_on_focus_lost also, this core feature/fix would need to be done sublimehq/sublime_text#3273

I was just looking into the main LSP package and came to the same conclusion: { "keys": ["ctrl+s"], "command": "lsp_save" } also has the same result.

So I think the issues is with the LSP package. It should hook into the save command instead as other packages do.

As for save_on_focus_lost, I don't think I have any solution for that.

Maybe I can make a custom hook for that. I'll have to dig into that. I'll check that issue and look into LSP further. Thanks for the help so far!

rchl commented

Other packages hook into the save command by hooking the sync API which creates a bad user experience due to freezing the editor momentarily. That's not an acceptable option, that's why I've created the core issue above.

Thanks, I subscribed to it and will keep an eye on it.

Might also be nice to have the primary key in LSP be configurable. Although I imagine OS hoppers who are stubborn like me are rare.