Skip to content

Instantly share code, notes, and snippets.

@Pangoraw
Last active November 6, 2024 10:21
Show Gist options
  • Save Pangoraw/e171ead112deacc6e5ffff949b1142b8 to your computer and use it in GitHub Desktop.
Save Pangoraw/e171ead112deacc6e5ffff949b1142b8 to your computer and use it in GitHub Desktop.
Run clang-format to format a buffer and keep the cursor location intact
local clang_format_bin = "clang-format"
local function run_clang(args, input, on_done)
local uv = vim.uv
local stdin = uv.new_pipe(false)
local stdout = uv.new_pipe(false)
local chunks = {}
local function on_read(err, data)
assert(not err, err)
if data then
table.insert(chunks, data)
end
end
local handle
handle, _ = uv.spawn(clang_format_bin, {
args = args,
stdio = { stdin, stdout, nil },
},
vim.schedule_wrap(function(code, signal)
stdout:read_stop()
stdout:close()
handle:close()
local output = table.concat(chunks)
on_done(output)
end))
uv.write(stdin, input)
stdin:close()
uv.read_start(stdout, on_read)
uv.run('once')
end
local function clang_format()
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
local input = table.concat(lines, "\n")
local cursor = vim.api.nvim_win_get_cursor(0)
local function on_done(output)
local new_lines = vim.split(output, "\n", { plain = true })
local json_message = table.remove(new_lines, 1)
local json_decoded = vim.json.decode(json_message)
vim.api.nvim_buf_set_lines(0, 0, -1, false, new_lines)
local new_cursor = json_decoded["Cursor"]
local row = 0
while row < #new_lines and new_cursor > vim.api.nvim_buf_get_offset(0, row + 1) do
row = row + 1
end
local col = new_cursor - vim.api.nvim_buf_get_offset(0, row)
vim.api.nvim_win_set_cursor(0, { row + 1, col })
end
local offset = cursor[2] + vim.api.nvim_buf_get_offset(0, cursor[1] - 1)
run_clang({ "--cursor=" .. tostring(offset), }, input, on_done)
end
vim.api.nvim_create_user_command("CF", clang_format, {})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment