Skip to content

Commit 2f7a796

Browse files
committed
fix(nvim): improve async safety, cross-platform support, and docs
1 parent 49bd5d4 commit 2f7a796

3 files changed

Lines changed: 41 additions & 9 deletions

File tree

docs/editor_integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ A modern Lua-based plugin for Neovim 0.10+ that provides asynchronous, non-block
8181

8282
#### Features
8383
- Fast formatting using `vim.system`.
84-
- Automatic fallback to `uvx snakefmt` if `snakefmt` is not in your environment.
84+
- Automatic fallback to `uv run --with snakefmt snakefmt` if `snakefmt` is not in your environment.
8585
- Configurable line length and auto-format on save.
8686

8787
#### Installation (with [lazy.nvim](https://github.com/folke/lazy.nvim))

lua/snakefmt/init.lua

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function M.setup(opts)
1212
group = group,
1313
pattern = { "*.smk", "Snakefile" },
1414
callback = function()
15-
M.format()
15+
M.format(true)
1616
end,
1717
desc = "Auto-format with snakefmt on save",
1818
})
@@ -32,14 +32,15 @@ function M.setup(opts)
3232
end, { desc = "Show snakefmt execution info" })
3333
end
3434

35-
function M.format()
35+
function M.format(sync)
3636
local cmd = paths.get_snakefmt_bin(config.options)
3737
if not cmd then
3838
vim.notify("snakefmt: binary not found and uvx fallback failed", vim.log.levels.ERROR)
3939
return
4040
end
4141

4242
local bufnr = vim.api.nvim_get_current_buf()
43+
local changedtick = vim.api.nvim_buf_get_changedtick(bufnr)
4344
local content = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
4445
local stdin = table.concat(content, "\n") .. "\n"
4546

@@ -51,12 +52,30 @@ function M.format()
5152
end
5253
table.insert(full_cmd, "-")
5354

55+
if sync then
56+
local obj = vim.system(full_cmd, { stdin = stdin }):wait()
57+
if obj.code == 0 then
58+
local formatted = vim.split(obj.stdout, "\n")
59+
if formatted[#formatted] == "" then
60+
table.remove(formatted)
61+
end
62+
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, formatted)
63+
else
64+
vim.notify("snakefmt error: " .. obj.stderr, vim.log.levels.ERROR)
65+
end
66+
return
67+
end
68+
5469
vim.system(full_cmd, { stdin = stdin }, function(obj)
5570
vim.schedule(function()
5671
if not vim.api.nvim_buf_is_valid(bufnr) then
5772
return
5873
end
5974

75+
if vim.api.nvim_buf_get_changedtick(bufnr) ~= changedtick then
76+
return
77+
end
78+
6079
if obj.code == 0 then
6180
local formatted = vim.split(obj.stdout, "\n")
6281
if formatted[#formatted] == "" then

lua/snakefmt/paths.lua

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,31 @@ function M.get_snakefmt_bin(config_opts)
99
-- 2. Local Environment ($VIRTUAL_ENV)
1010
local venv = os.getenv("VIRTUAL_ENV")
1111
if venv then
12-
local path = venv .. "/bin/snakefmt"
13-
if vim.fn.executable(path) == 1 then
14-
return { path }
12+
local candidates = {
13+
venv .. "/bin/snakefmt",
14+
venv .. "/Scripts/snakefmt.exe",
15+
venv .. "/Scripts/snakefmt",
16+
}
17+
for _, path in ipairs(candidates) do
18+
if vim.fn.executable(path) == 1 then
19+
return { path }
20+
end
1521
end
1622
end
1723

1824
-- 3. Project Environment (.venv)
1925
local project_venv = vim.fn.finddir(".venv", ".;")
2026
if project_venv ~= "" then
21-
local path = vim.fn.fnamemodify(project_venv, ":p") .. "bin/snakefmt"
22-
if vim.fn.executable(path) == 1 then
23-
return { path }
27+
local venv_base = vim.fn.fnamemodify(project_venv, ":p")
28+
local candidates = {
29+
venv_base .. "bin/snakefmt",
30+
venv_base .. "Scripts/snakefmt.exe",
31+
venv_base .. "Scripts/snakefmt",
32+
}
33+
for _, path in ipairs(candidates) do
34+
if vim.fn.executable(path) == 1 then
35+
return { path }
36+
end
2437
end
2538
end
2639

0 commit comments

Comments
 (0)