bug: astyle windows range formatting
Neovim version (nvim -v)
v0.9.5
Operating system/version
windows 11
Add the debug logs
- [X] I have set
log_level = vim.log.levels.DEBUGand pasted the log contents below.
Log file
17:48:58[DEBUG] Running formatters on C:\hello_world\main.cpp: { "astyle" }
17:48:58[INFO] Run astyle on C:\hello_world\main.cpp
17:48:58[TRACE] Input lines: { "#include <iostream>", "", "int main(int argc, char** argv){", '\tstd::cout << "Hello World" << std::endl;', "\treturn 0;", "}", "", "", " const int toto = 0;", "" }
17:48:58[DEBUG] Run command: { "astyle", "--project", "--quiet" }
17:48:58[DEBUG] Run CWD: C:/hello_world
17:48:58[DEBUG] astyle exited with code 0
17:48:58[TRACE] Output lines: { "#include <iostream>\r", "\r", "int main(int argc, char** argv)\r", "{\r", ' std::cout << "Hello World" << std::endl;\r', " return 0;\r", "}\r", "\r", "\r", "const int toto = 0;\r", "\r" }
17:48:58[TRACE] astyle stderr: { "" }
17:48:58[TRACE] Applying formatting to C:\hello_world\main.cpp
17:48:58[TRACE] Comparing lines { "#include <iostream>", "", "int main(int argc, char** argv){", '\tstd::cout << "Hello World" << std::endl;', "\treturn 0;", "}", "", "", " const int toto = 0;", "" } and { "#include <iostream>\r", "\r", "int main(int argc, char** argv)\r", "{\r", ' std::cout << "Hello World" << std::endl;\r', " return 0;\r", "}\r", "\r", "\r", "const int toto = 0;\r", "\r" }
17:48:58[TRACE] Diff indices { { 1, 10, 1, 11 } }
17:48:58[TRACE] Applying text edits: { {
newText = '\r\n\r\nint main(int argc, char** argv)\r\n{\r\n std::cout << "Hello World" << std::endl;\r\n return 0;\r\n}\r\n\r\n\r\nconst int toto = 0;\r\n\r',
range = {
["end"] = {
character = 0,
line = 9
},
start = {
character = 19,
line = 0
}
}
} }
17:48:58[TRACE] Done formatting C:\hello_world\main.cpp
Describe the bug
Range formatting isn't working with astyle on Windows. Instead, the entire file is formatted.
What is the severity of this bug?
tolerable (can work around it)
Steps To Reproduce
- nvim -u repro.lua hello_world.cpp
- select the main function
- type
cf to call the conform.nvim - the entire file is formated (including the
const int totoline
Expected Behavior
Only the selection should have been formatted.
Minimal example file
#include <iostream>
int main(int argc, char** argv){ // space before { missing
std::cout << "Hello World" << std::endl;
return 0;
}
const int toto = 0; // leading space to remove
Minimal init.lua
-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")
-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end
-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"--single-branch",
"https://github.com/folke/lazy.nvim.git",
lazypath,
})
end
vim.opt.runtimepath:prepend(lazypath)
-- install plugins
local plugins = {
"folke/tokyonight.nvim",
{
"stevearc/conform.nvim",
config = function()
require("conform").setup({
log_level = vim.log.levels.DEBUG,
-- add your config here
formatters_by_ft = {cpp = {"astyle"}},
})
end,
},
-- add any other plugins here
}
require("lazy").setup(plugins, {
root = root .. "/plugins",
})
vim.cmd.colorscheme("tokyonight")
-- add anything else here
vim.keymap.set({ "n", "v" }, "<space>cf", function()
require("conform").format({})
end, { desc = "Format" })
Additional context
In the log, Output lines: { "#include <iostream>\r", did you notice the \r ? It is not in the input line, so the minimal diff will detect the entire file as different.
The additional \r is due to this line https://github.com/stevearc/conform.nvim/blob/192a6d2ddace343f1840a8f72efe2315bd392243/lua/conform/runner.lua#L322
I think this is due to jobstart, on_stdout,
{data} Raw data (readfile()-style list of strings) read from the channel. EOF is a single-item list: ['']. First and last items may be partial lines!
in readfile() doc
When the last line ends in a NL an extra empty list item is added. No CR characters are removed. Otherwise: CR characters that appear before a NL are removed. Whether the last line ends in a NL or not does not matter.
But I don't understand it as the two bold sentences seems contradictory.
In any case, replacing https://github.com/stevearc/conform.nvim/blob/192a6d2ddace343f1840a8f72efe2315bd392243/lua/conform/runner.lua#L330 with
stdout = vim.tbl_map(function (item) return item:gsub("\r$", "") end, data)
Fix the bug.
Formatting a file with astyle was moving all diagnostics from my lsp to the bottom of the file when the option squeeze-line was on. It was also adding a new line at the bottom of the file every time when squeeze-line was off. Applying the suggested fix fixed both.
I'm running nvim 0.9.5 on windows 11 as well.