stevearc / conform.nvim

Lightweight yet powerful formatter plugin for Neovim
MIT License
3.18k stars 162 forks source link

bug: Blank line at EOF with powershell_es #274

Closed MarcoBuess closed 9 months ago

MarcoBuess commented 10 months ago

Neovim version (nvim -v)

0.9.4

Operating system/version

Windows 10.0.19045

Add the debug logs

Log file

Log file: C:\Users\****\AppData\Local\nvim-data\conform.log
          13:09:11[DEBUG] Running LSP formatter on c:\****\****\Set-Up.ps1
          13:09:11[DEBUG] Converting full-file LSP format to piecewise format
          13:11:29[DEBUG] Running LSP formatter on c:\****\test.ps1
          13:11:29[DEBUG] Converting full-file LSP format to piecewise format
          13:11:31[DEBUG] Running LSP formatter on c:\****\test.ps1
          13:11:31[DEBUG] Converting full-file LSP format to piecewise format
          13:11:47[DEBUG] Running LSP formatter on c:\****\test.ps1
          13:11:47[DEBUG] Converting full-file LSP format to piecewise format

Formatters for this buffer:
LSP: powershell_es

Other formatters:
stylua ready (lua) C:\Users\****\AppData\Local\nvim-data\mason\bin\stylua.CMD

Describe the bug

When using format on save, a new line gets added at EOF. Disabling conform.nvim and formatting with vim.lsp.buf.format() doesn't show this behavior.

What is the severity of this bug?

minor (annoyance)

Steps To Reproduce

  1. Open .ps1 file
  2. Save with format_on_save enabled.

Expected Behavior

Code gets formatted but no new line added at EOF.

Minimal example file

Write-Output -InputObject "Hello, World!"

Minimal init.lua

Minimal lazy spec:

{
    "stevearc/conform.nvim",
    dependencies = { "williamboman/mason.nvim" },
    event = { "BufWritePre" },
    cmd = { "ConformInfo" },
    opts = {
        formatters_by_ft = {
            lua = { "stylua" },
        },
        format_on_save = { timeout_ms = 500, lsp_fallback = true },
        log_level = vim.log.levels.DEBUG,
    },
},

Additional context

No response

MarcoBuess commented 10 months ago

No biggy. The main reason I was using conform.nvim was because of how easy custom formatters (mainly stylua) can be integrated. I just figured lua_ls provides me with the necessary options I use for stylua out of the box, so I was able to ditch conform.nvim alltogether. You might still want to look into this. Otherwise cool plugin, I might come back later in case I have something that has no built in formatting via lsp. Cheers.

scottmckendry commented 9 months ago

Not sure if this is helpful in your situation but I could not get the LSP formatting to work with powershell_es. As a workaround, I'm using a custom formatter based on Invoke-Formatter from the PSScriptAnalyzer module.

Here is my conform configuration: https://github.com/scottmckendry/Windots/blob/main/nvim/lua/plugins/conform.lua

So far it's been fairly reliable, my only qualm is that it does not support Unicode characters, so no emojis or nerd font icons in scripts :(

stevearc commented 9 months ago

I have a suspicion about what is happening, but I'll need some more logs to confirm it. Could you format a small file that exhibits this error with log_level = vim.log.levels.TRACE and provide the logs? I just need to see what the raw output of the LSP format operation is.

scottmckendry commented 9 months ago

I know this was originally raised for the PowerShell LSP formatter, but I'm having a very similar problem with the Bicep LSP with conform where new lines are inserted just before the final closing brace. For example, the file looks like this before saving:

resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {
    name: 'deleteLock'
    scope: resourceGroup()
    properties: {
        level: 'CanNotDelete'
    }
}

After saving, it looks like this:

resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {
    name: 'deleteLock'
    scope: resourceGroup()
    properties: {
        level: 'CanNotDelete'
    }

}

Then from the second save onwards there are two new lines at this position:

resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {
    name: 'deleteLock'
    scope: resourceGroup()
    properties: {
        level: 'CanNotDelete'
    }

}

The resulting logs of three saves in a row on the example above:

07:06:14[DEBUG] Running formatters on C:\Users\Scott\Git\Windots\test.bicep: {}
07:06:14[DEBUG] Running LSP formatter on C:\Users\Scott\Git\Windots\test.bicep
07:06:14[DEBUG] Converting full-file LSP format to piecewise format
07:06:14[TRACE] Applying formatting to C:\Users\Scott\Git\Windots\test.bicep
07:06:14[TRACE] Comparing lines { "resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {", "    name: 'deleteLock'", "    scope: resourceGroup()", "    properties: {", "        level: 'CanNotDelete'", "    }", "}" } and { "resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {\r", "    name: 'deleteLock'\r", "    scope: resourceGroup()\r", "    properties: {\r", "        level: 'CanNotDelete'\r", "    }\r", "}" }
07:06:14[TRACE] Diff indices { { 1, 6, 1, 6 } }
07:06:14[TRACE] Applying text edits: { {
    newText = "\r\n    name: 'deleteLock'\r\n    scope: resourceGroup()\r\n    properties: {\r\n        level: 'CanNotDelete'\r\n    }\r",
    range = {
      ["end"] = {
        character = 5,
        line = 5
      },
      start = {
        character = 84,
        line = 0
      }
    }
  } }
07:06:14[TRACE] Done formatting C:\Users\Scott\Git\Windots\test.bicep
07:06:17[DEBUG] Running formatters on C:\Users\Scott\Git\Windots\test.bicep: {}
07:06:17[DEBUG] Running LSP formatter on C:\Users\Scott\Git\Windots\test.bicep
07:06:17[DEBUG] Converting full-file LSP format to piecewise format
07:06:17[TRACE] Applying formatting to C:\Users\Scott\Git\Windots\test.bicep
07:06:17[TRACE] Comparing lines { "resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {", "    name: 'deleteLock'", "    scope: resourceGroup()", "    properties: {", "        level: 'CanNotDelete'", "    }", "", "}" } and { "resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {\r", "    name: 'deleteLock'\r", "    scope: resourceGroup()\r", "    properties: {\r", "        level: 'CanNotDelete'\r", "    }\r", "\r", "}" }
07:06:17[TRACE] Diff indices { { 1, 7, 1, 7 } }
07:06:17[TRACE] Applying text edits: { {
    newText = "\r\n    name: 'deleteLock'\r\n    scope: resourceGroup()\r\n    properties: {\r\n        level: 'CanNotDelete'\r\n    }\r\n\r",
    range = {
      ["end"] = {
        character = 0,
        line = 6
      },
      start = {
        character = 84,
        line = 0
      }
    }
  } }
07:06:17[TRACE] Done formatting C:\Users\Scott\Git\Windots\test.bicep
07:07:08[DEBUG] Running formatters on C:\Users\Scott\Git\Windots\test.bicep: {}
07:07:08[DEBUG] Running LSP formatter on C:\Users\Scott\Git\Windots\test.bicep
07:07:08[DEBUG] Converting full-file LSP format to piecewise format
07:07:08[TRACE] Applying formatting to C:\Users\Scott\Git\Windots\test.bicep
07:07:08[TRACE] Comparing lines { "resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {", "    name: 'deleteLock'", "    scope: resourceGroup()", "    properties: {", "        level: 'CanNotDelete'", "    }", "", "", "}" } and { "resource rgDeleteLock 'Microsoft.Authorization/locks@2016-09-01' = if (deleteLock) {\r", "    name: 'deleteLock'\r", "    scope: resourceGroup()\r", "    properties: {\r", "        level: 'CanNotDelete'\r", "    }\r", "\r", "}" }
07:07:08[TRACE] Diff indices { { 1, 8, 1, 7 } }
07:07:08[TRACE] Applying text edits: { {
    newText = "\r\n    name: 'deleteLock'\r\n    scope: resourceGroup()\r\n    properties: {\r\n        level: 'CanNotDelete'\r\n    }\r\n\r",
    range = {
      ["end"] = {
        character = 0,
        line = 7
      },
      start = {
        character = 84,
        line = 0
      }
    }
  } }
07:07:08[TRACE] Done formatting C:\Users\Scott\Git\Windots\test.bicep

Let me know if any further info is required.

stevearc commented 9 months ago

Thanks for the logs! This confirms my suspicion that it is related to the line endings. I've pushed up what I believe to be a fix. Could you give it a try?

scottmckendry commented 9 months ago

Brilliant! That's fixed it for the Bicep LSP. @MarcoBuess may be able to advise RE PowerShell.

stevearc commented 9 months ago

Will close as fixed. Feel free to re-open if issue persists