diff options
author | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-06-20 23:46:00 +0200 |
---|---|---|
committer | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-06-20 23:46:00 +0200 |
commit | a0f45aece21a6280633023ec84f60eb0d5e0849a (patch) | |
tree | 3d8d0e8294e84606ffea97e524be1cb94cdf8cb4 /config/essentials/vis/format.lua | |
parent | 2f8816e47e0797083a667d5cf7e778940dd1f789 (diff) |
checkpoint
Diffstat (limited to 'config/essentials/vis/format.lua')
-rw-r--r-- | config/essentials/vis/format.lua | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/config/essentials/vis/format.lua b/config/essentials/vis/format.lua new file mode 100644 index 0000000..15488dd --- /dev/null +++ b/config/essentials/vis/format.lua @@ -0,0 +1,131 @@ +local global_options = {check_same = true} + +local function stdio_formatter(cmd, options) + local function apply(win, range, pos) + local size = win.file.size + local all = {start = 0, finish = size} + if range == nil then range = all end + local command = type(cmd) == 'function' and cmd(win, range, pos) or cmd + local check_same = (options and options.check_same ~= nil) and + options.check_same or global_options.check_same + local check = check_same == true or + (type(check_same) == 'number' and check_same >= size) + local status, out, err = vis:pipe(win.file, all, command) + if status ~= 0 then + vis:message(err) + elseif out == nil or out == '' then + vis:info('No output from formatter') + elseif not check or win.file:content(all) ~= out then + local start, finish = range.start, range.finish + win.file:delete(range) + win.file:insert(start, + out:sub(start + 1, finish + (out:len() - size))) + end + return pos + end + return { + apply = apply, + options = options or {ranged = type(cmd) == 'function'} + } +end + +local function with_filename(win, option) + if win.file.path then + return option .. "'" .. win.file.path:gsub("'", "\\'") .. "'" + else + return '' + end +end + +local formatters = {} +formatters = { + bash = stdio_formatter(function(win) + return 'shfmt ' .. with_filename(win, '--filename ') .. ' -' + end), + csharp = stdio_formatter('dotnet csharpier'), + go = stdio_formatter('gofmt'), + lua = { + pick = function(win) + local _, out = vis:pipe(win.file, + {start = 0, finish = win.file.size}, + 'test -e .lua-format && echo luaformatter || echo stylua') + return formatters[out:gsub('\n$', '')] + end + }, + luaformatter = stdio_formatter('lua-format'), + markdown = stdio_formatter(function(win) + if win.options and win.options.colorcolumn ~= 0 then + return 'prettier --parser markdown --prose-wrap always ' .. + ('--print-width ' .. (win.options.colorcolumn - 1) .. ' ') .. + with_filename(win, '--stdin-filepath ') + else + return 'prettier --parser markdown ' .. + with_filename(win, '--stdin-filepath ') + end + end, {ranged = false}), + powershell = stdio_formatter([[ + "$( (command -v powershell.exe || command -v pwsh) 2>/dev/null )" -c ' + Invoke-Formatter -ScriptDefinition ` + ([IO.StreamReader]::new([Console]::OpenStandardInput()).ReadToEnd()) + ' | sed -e :a -e '/^[\r\n]*$/{$d;N;};/\n$/ba' + ]]), + rust = stdio_formatter('rustfmt'), + stylua = stdio_formatter(function(win, range) + if range and (range.start ~= 0 or range.finish ~= win.file.size) then + return + 'stylua -s --range-start ' .. range.start .. ' --range-end ' .. + range.finish .. with_filename(win, ' --stdin-filepath ') .. + ' -' + else + return 'stylua -s ' .. with_filename(win, '--stdin-filepath ') .. + ' -' + end + end), + text = stdio_formatter(function(win) + if win.options and win.options.colorcolumn ~= 0 then + return 'fmt -w ' .. (win.options.colorcolumn - 1) + else + return 'fmt' + end + end, {ranged = false}) +} + +local function getwinforfile(file) + for win in vis:windows() do + if win and win.file and win.file.path == file.path then + return win + end + end +end + +local function apply(file_or_keys, range, pos) + local win = + type(file_or_keys) ~= 'string' and getwinforfile(file_or_keys) or + vis.win + local ret = type(file_or_keys) ~= 'string' and function() return pos end or + function() return 0 end + pos = pos or win.selection.pos + local formatter = formatters[win.syntax] + if formatter and formatter.pick then formatter = formatter.pick(win) end + if formatter == nil then + vis:info('No formatter for ' .. win.syntax) + return ret() + end + if range ~= nil and not formatter.options.ranged and range.start ~= 0 and + range.finish ~= win.file.size then + vis:info('Formatter for ' .. win.syntax .. ' does not support ranges') + return ret() + end + pos = formatter.apply(win, range, pos) or pos + vis:insert('') -- redraw and friends don't work + win.selection.pos = pos + return ret() +end + +return { + formatters = formatters, + options = global_options, + apply = apply, + stdio_formatter = stdio_formatter, + with_filename = with_filename +} |