mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-04-13 13:59:10 +08:00
feat(format.lua) add format.lua
This commit is contained in:
parent
ae6b976930
commit
1d8dbeb8bb
@ -1,7 +1,6 @@
|
||||
# SpaceVim
|
||||
|
||||
[](https://twitter.com/SpaceVim)
|
||||
[](development/#证书)
|
||||
|
||||
SpaceVim is a modular configuration of Vim and Neovim.
|
||||
It's inspired by spacemacs. It manages collections of plugins in layers,
|
||||
@ -23,7 +22,4 @@ what packages to install.
|
||||
|
||||
- English: [https://spacevim.org/development/](https://spacevim.org/development/)
|
||||
- Chinese: [https://spacevim.org/cn/development/](https://spacevim.org/cn/development/)
|
||||
|
||||
|
||||
|
||||
<!-- vim:set nowrap: -->
|
||||
|
@ -16,7 +16,7 @@
|
||||
"
|
||||
" 1. `format_on_save`: disabled by default.
|
||||
" 2. `format_method`: set the format plugin, default plugin is `neoformat`.
|
||||
" You can also use `vim-codefmt`.
|
||||
" You can also use `vim-codefmt` or `format.nvim`
|
||||
" 3. `silent_format`: Runs the formatter without any messages.
|
||||
" 4. `format_notify_width`: set the neoformat notify window width.
|
||||
" 5. `format_notify_timeout`: set the neoformat notify clear timeout. default
|
||||
@ -57,6 +57,10 @@ function! SpaceVim#layers#format#plugins() abort
|
||||
\ ['google/vim-glaive', {'merged' : 0, 'loadconf' : 1}],
|
||||
\ ['google/vim-codefmt', {'merged' : 0}],
|
||||
\ ]
|
||||
elseif s:format_method ==# 'format.nvim'
|
||||
return [
|
||||
\ [g:_spacevim_root_dir . 'bundle/format.nvim', {'merged' : 0, 'loadconf' : 1, 'loadconf_before' : 1}],
|
||||
\ ]
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -66,6 +70,8 @@ function! SpaceVim#layers#format#config() abort
|
||||
call SpaceVim#mapping#space#def('nnoremap', ['b', 'f'], 'Neoformat', 'format-code', 1)
|
||||
elseif s:format_method ==# 'codefmt'
|
||||
call SpaceVim#mapping#space#def('nnoremap', ['b', 'f'], 'FormatCode', 'format-code', 1)
|
||||
elseif s:format_method ==# 'format.nvim'
|
||||
call SpaceVim#mapping#space#def('nnoremap', ['b', 'f'], 'Format', 'format-code', 1)
|
||||
endif
|
||||
augroup spacevim_layer_format
|
||||
autocmd!
|
||||
@ -118,6 +124,8 @@ function! s:format() abort
|
||||
undojoin | Neoformat
|
||||
elseif s:format_method ==# 'codefmt'
|
||||
undojoin | FormatCode
|
||||
elseif s:format_method ==# 'format.nvim'
|
||||
undojoin | Format
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
34
bundle/format.nvim/lua/format.lua
Normal file
34
bundle/format.nvim/lua/format.lua
Normal file
@ -0,0 +1,34 @@
|
||||
local M = {}
|
||||
|
||||
local util = require('format.util')
|
||||
local task = require('format.task')
|
||||
|
||||
function M.format(bang, user_input, start_line, end_line)
|
||||
if not vim.o.modifiable then
|
||||
return util.msg('buffer is not modifiable!')
|
||||
end
|
||||
|
||||
local filetype = vim.o.filetype
|
||||
|
||||
if filetype == '' then
|
||||
return util.msg('format: skip empty filetype')
|
||||
end
|
||||
|
||||
local ok, default_formatter = pcall(require, 'format.ft.' .. filetype)
|
||||
|
||||
if not ok then
|
||||
return util.msg('no formatter for ' .. filetype)
|
||||
end
|
||||
|
||||
task.run({
|
||||
bufnr = vim.fn.bufnr(),
|
||||
stdin = vim.api.nvim_buf_get_lines(0, start_line - 1, end_line - 1, false),
|
||||
start_line = start_line - 1,
|
||||
end_line = end_line - 1,
|
||||
formatter = default_formatter
|
||||
})
|
||||
end
|
||||
|
||||
function M.setup(opts) end
|
||||
|
||||
return M
|
5
bundle/format.nvim/lua/format/config.lua
Normal file
5
bundle/format.nvim/lua/format/config.lua
Normal file
@ -0,0 +1,5 @@
|
||||
local M = {}
|
||||
|
||||
M.custom_formatters = {}
|
||||
|
||||
return M
|
5
bundle/format.nvim/lua/format/ft/lua.lua
Normal file
5
bundle/format.nvim/lua/format/ft/lua.lua
Normal file
@ -0,0 +1,5 @@
|
||||
return {
|
||||
exe = 'stylua',
|
||||
args = {'-'},
|
||||
stdin = true
|
||||
}
|
8
bundle/format.nvim/lua/format/ft/markdown.lua
Normal file
8
bundle/format.nvim/lua/format/ft/markdown.lua
Normal file
@ -0,0 +1,8 @@
|
||||
if vim.fn.executable('prettier') == 1 then
|
||||
return {
|
||||
exe = vim.fn.exepath('prettier'),
|
||||
name = 'prettier',
|
||||
args = {'--stdin-filepath', 't.md'},
|
||||
stdin = true
|
||||
}
|
||||
end
|
93
bundle/format.nvim/lua/format/task.lua
Normal file
93
bundle/format.nvim/lua/format/task.lua
Normal file
@ -0,0 +1,93 @@
|
||||
local M = {}
|
||||
|
||||
local jobid = -1
|
||||
|
||||
local job = require('spacevim.api.job')
|
||||
local util = require('format.util')
|
||||
|
||||
local stdout = {}
|
||||
local stderr = {}
|
||||
local current_task
|
||||
|
||||
local function on_stdout(id, data)
|
||||
for _, v in ipairs(data) do
|
||||
table.insert(stdout, v)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_stderr(id, data)
|
||||
for _, v in ipairs(data) do
|
||||
table.insert(stderr, v)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_exit(id, code, single)
|
||||
util.info(
|
||||
'formatter: '
|
||||
.. (current_task.formatter.name or current_task.formatter.exe)
|
||||
.. ' exit code:'
|
||||
.. code
|
||||
.. ' single:'
|
||||
.. single
|
||||
)
|
||||
if code == 0 and single == 0 then
|
||||
if current_task.formatter.use_stderr then
|
||||
vim.api.nvim_buf_set_lines(
|
||||
current_task.bufnr,
|
||||
current_task.start_line,
|
||||
current_task.end_line,
|
||||
false,
|
||||
stderr
|
||||
)
|
||||
else
|
||||
if table.concat(stdout, '\n') == table.concat(current_task.stdin, '\n') then
|
||||
util.msg('no necessary changes')
|
||||
else
|
||||
util.msg((current_task.formatter.name or current_task.formatter.exe) .. ' formatted buffer')
|
||||
vim.api.nvim_buf_set_lines(
|
||||
current_task.bufnr,
|
||||
current_task.start_line,
|
||||
current_task.end_line,
|
||||
false,
|
||||
stdout
|
||||
)
|
||||
end
|
||||
end
|
||||
else
|
||||
util.msg('formatter ' .. current_task.formatter.exe .. ' failed to run')
|
||||
end
|
||||
|
||||
jobid = -1
|
||||
end
|
||||
|
||||
function M.run(task)
|
||||
if jobid > 0 then
|
||||
util.msg('previous formatting command has not ended')
|
||||
return
|
||||
end
|
||||
|
||||
util.info('running formatter: ' .. task.formatter.exe)
|
||||
|
||||
local cmd = { task.formatter.exe }
|
||||
for _, v in ipairs(task.formatter.args) do
|
||||
table.insert(cmd, v)
|
||||
end
|
||||
stdout = {}
|
||||
stderr = {}
|
||||
current_task = task
|
||||
jobid = job.start(cmd, {
|
||||
on_stdout = on_stdout,
|
||||
on_stderr = on_stderr,
|
||||
on_exit = on_exit,
|
||||
})
|
||||
|
||||
if jobid == -1 then
|
||||
return util.msg('formatter is not executable: ' .. task.formatter.exe)
|
||||
end
|
||||
|
||||
if task.formatter.stdin then
|
||||
job.send(jobid, task.stdin)
|
||||
job.send(jobid, nil)
|
||||
end
|
||||
end
|
||||
return M
|
14
bundle/format.nvim/lua/format/util.lua
Normal file
14
bundle/format.nvim/lua/format/util.lua
Normal file
@ -0,0 +1,14 @@
|
||||
local M = {}
|
||||
local nt = require('spacevim.api.notify')
|
||||
|
||||
local log = require('spacevim.logger').derive('format')
|
||||
|
||||
function M.msg(msg)
|
||||
nt.notify(msg)
|
||||
end
|
||||
|
||||
function M.info(msg)
|
||||
log.info(msg)
|
||||
end
|
||||
|
||||
return M
|
8
bundle/format.nvim/plugin/format.lua
Normal file
8
bundle/format.nvim/plugin/format.lua
Normal file
@ -0,0 +1,8 @@
|
||||
vim.api.nvim_create_user_command('Format', function(opts)
|
||||
require('format').format(opts.bang, opts.args, opts.line1, opts.line2)
|
||||
end, {
|
||||
nargs = '*',
|
||||
range = '%',
|
||||
bang = true,
|
||||
bar = true
|
||||
})
|
@ -2243,7 +2243,7 @@ LAYER OPTIONS
|
||||
|
||||
1. `format_on_save`: disabled by default.
|
||||
2. `format_method`: set the format plugin, default plugin is `neoformat`.
|
||||
You can also use `vim-codefmt`.
|
||||
You can also use `vim-codefmt` or `format.nvim`
|
||||
3. `silent_format`: Runs the formatter without any messages.
|
||||
4. `format_notify_width`: set the neoformat notify window width.
|
||||
5. `format_notify_timeout`: set the neoformat notify clear timeout. default
|
||||
|
@ -2627,5 +2627,4 @@ export PATH=$PATH:$HOME/.SpaceVim/bin
|
||||
```
|
||||
|
||||
Use `svc` to open a file in the existing Vim server, or use `nsvc` to open a file in the existing Neovim server.
|
||||
|
||||

|
||||
|
@ -23,7 +23,6 @@ The `format` layer provides code formatting for SpaceVim, with support for
|
||||
[`codefmt`](https://github.com/google/vim-codefmt) underlying code
|
||||
formatting plugins.
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
This layer is enabled by default. If you want to disable it, add the following to your configuration file:
|
||||
@ -71,7 +70,7 @@ This layer is enabled by default. If you want to disable it, add the following t
|
||||
```
|
||||
|
||||
- **`silent_format`**: Setting this to true will run the formatter silently without any messages. Default is
|
||||
disabled.
|
||||
disabled.
|
||||
|
||||
```toml
|
||||
[[layers]]
|
||||
@ -84,10 +83,8 @@ disabled.
|
||||
neoformat is a formatting framework, all of it's options can be used in bootstrap function. You can read
|
||||
`:help neoformat` for more info.
|
||||
|
||||
|
||||
Here is an example for add formatter for java file, and it has been included into `lang#java` layer:
|
||||
|
||||
|
||||
```viml
|
||||
let g:neoformat_enabled_java = ['googlefmt']
|
||||
let g:neoformat_java_googlefmt = {
|
||||
@ -99,6 +96,6 @@ let g:neoformat_java_googlefmt = {
|
||||
|
||||
## Key bindings
|
||||
|
||||
| Key binding | Description |
|
||||
| ----------- | ------------------------------------- |
|
||||
| Key binding | Description |
|
||||
| ----------- | ----------- |
|
||||
| `SPC b f` | format whole buffer or selected lines |
|
||||
|
@ -46,28 +46,28 @@ local function new_job_obj(id, handle, opt, state)
|
||||
end
|
||||
|
||||
local function default_dev() -- {{{
|
||||
local env = vim.fn.environ()
|
||||
env['NVIM'] = vim.v.servername
|
||||
env['NVIM_LISTEN_ADDRESS'] = nil
|
||||
env['NVIM_LOG_FILE'] = nil
|
||||
env['VIMRUNTIME'] = nil
|
||||
return env
|
||||
local env = vim.fn.environ()
|
||||
env['NVIM'] = vim.v.servername
|
||||
env['NVIM_LISTEN_ADDRESS'] = nil
|
||||
env['NVIM_LOG_FILE'] = nil
|
||||
env['VIMRUNTIME'] = nil
|
||||
return env
|
||||
end
|
||||
-- }}}
|
||||
|
||||
local function setup_env(env, clear_env) -- {{{
|
||||
if clear_env then
|
||||
return env
|
||||
end
|
||||
--- @type table<string,string|number>
|
||||
env = vim.tbl_extend('force', default_dev(), env or {})
|
||||
if clear_env then
|
||||
return env
|
||||
end
|
||||
--- @type table<string,string|number>
|
||||
env = vim.tbl_extend('force', default_dev(), env or {})
|
||||
|
||||
local renv = {} --- @type string[]
|
||||
for k, v in pairs(env) do
|
||||
renv[#renv + 1] = string.format('%s=%s', k, tostring(v))
|
||||
end
|
||||
local renv = {} --- @type string[]
|
||||
for k, v in pairs(env) do
|
||||
renv[#renv + 1] = string.format('%s=%s', k, tostring(v))
|
||||
end
|
||||
|
||||
return renv
|
||||
return renv
|
||||
end
|
||||
-- }}}
|
||||
|
||||
@ -157,7 +157,7 @@ function M.start(cmd, opts)
|
||||
if data then
|
||||
local stdout_data
|
||||
_jobs['jobid_' .. current_id].state.stdout_eof, stdout_data =
|
||||
buffered_data(_jobs['jobid_' .. current_id].state.stdout_eof, data)
|
||||
buffered_data(_jobs['jobid_' .. current_id].state.stdout_eof, data)
|
||||
vim.schedule(function()
|
||||
opts.on_stdout(current_id, stdout_data)
|
||||
end)
|
||||
@ -168,7 +168,7 @@ function M.start(cmd, opts)
|
||||
if data then
|
||||
local stdout_data
|
||||
_jobs['jobid_' .. current_id].state.stdout_eof, stdout_data =
|
||||
buffered_data(_jobs['jobid_' .. current_id].state.stdout_eof, data)
|
||||
buffered_data(_jobs['jobid_' .. current_id].state.stdout_eof, data)
|
||||
vim.schedule(function()
|
||||
opts.on_stdout(current_id, stdout_data, 'stdout')
|
||||
end)
|
||||
@ -184,7 +184,7 @@ function M.start(cmd, opts)
|
||||
if data then
|
||||
local stderr_data
|
||||
_jobs['jobid_' .. current_id].state.stderr_eof, stderr_data =
|
||||
buffered_data(_jobs['jobid_' .. current_id].state.stderr_eof, data)
|
||||
buffered_data(_jobs['jobid_' .. current_id].state.stderr_eof, data)
|
||||
vim.schedule(function()
|
||||
opts.on_stderr(current_id, stderr_data)
|
||||
end)
|
||||
@ -195,7 +195,7 @@ function M.start(cmd, opts)
|
||||
if data then
|
||||
local stderr_data
|
||||
_jobs['jobid_' .. current_id].state.stderr_eof, stderr_data =
|
||||
buffered_data(_jobs['jobid_' .. current_id].state.stderr_eof, data)
|
||||
buffered_data(_jobs['jobid_' .. current_id].state.stderr_eof, data)
|
||||
vim.schedule(function()
|
||||
opts.on_stderr(current_id, stderr_data, 'stderr')
|
||||
end)
|
||||
@ -207,35 +207,35 @@ function M.start(cmd, opts)
|
||||
end
|
||||
|
||||
function M.send(id, data) -- {{{
|
||||
local jobobj = _jobs['jobid_' .. id]
|
||||
local jobobj = _jobs['jobid_' .. id]
|
||||
|
||||
if not jobobj then
|
||||
error('can not find job:' .. id)
|
||||
end
|
||||
if not jobobj then
|
||||
error('can not find job:' .. id)
|
||||
end
|
||||
|
||||
local stdin = jobobj.state.stdin
|
||||
local stdin = jobobj.state.stdin
|
||||
|
||||
if not stdin then
|
||||
error('no stdin stream for jobid:' .. id)
|
||||
end
|
||||
if not stdin then
|
||||
error('no stdin stream for jobid:' .. id)
|
||||
end
|
||||
|
||||
if type(data) == 'table' then
|
||||
for _, v in ipairs(data) do
|
||||
stdin:write(v)
|
||||
stdin:write('\n')
|
||||
end
|
||||
elseif type(data) == 'string' then
|
||||
stdin:write(data)
|
||||
if type(data) == 'table' then
|
||||
for _, v in ipairs(data) do
|
||||
stdin:write(v)
|
||||
stdin:write('\n')
|
||||
elseif data == nil then
|
||||
stdin:write('', function()
|
||||
stdin:shutdown(function()
|
||||
if stdin then
|
||||
stdin:close()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
elseif type(data) == 'string' then
|
||||
stdin:write(data)
|
||||
stdin:write('\n')
|
||||
elseif data == nil then
|
||||
stdin:write('', function()
|
||||
stdin:shutdown(function()
|
||||
if stdin then
|
||||
stdin:close()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function M.chanclose(id, t)
|
||||
@ -245,14 +245,12 @@ function M.chanclose(id, t)
|
||||
error('can not find job:' .. id)
|
||||
end
|
||||
if t == 'stdin' then
|
||||
-- close stdio
|
||||
local stdin = jobobj.state.stdin
|
||||
if not stdin then
|
||||
stdin:shutdown(function()
|
||||
if stdin then
|
||||
stdin:close()
|
||||
end
|
||||
end)
|
||||
if stdin and stdin:is_active() then
|
||||
stdin:close()
|
||||
end
|
||||
|
||||
elseif t == 'stdout' then
|
||||
elseif t == 'stderr' then
|
||||
else
|
||||
@ -267,12 +265,6 @@ function M.stop(id)
|
||||
return
|
||||
end
|
||||
|
||||
-- close stdio
|
||||
local stdin = jobobj.state.stdin
|
||||
if stdin and stdin:is_active() then
|
||||
stdin:close()
|
||||
end
|
||||
|
||||
local handle = jobobj.handle
|
||||
handle:kill(6)
|
||||
end
|
||||
|
40
lua/spacevim/api/neojob.lua
Normal file
40
lua/spacevim/api/neojob.lua
Normal file
@ -0,0 +1,40 @@
|
||||
local job = require('spacevim.api.job')
|
||||
local nt = require('spacevim.api.notify')
|
||||
|
||||
local text = {}
|
||||
local function on_stdout(id, data)
|
||||
nt.notify('stdout:' .. #data)
|
||||
for _, v in ipairs(data) do
|
||||
table.insert(text, v)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_stderr(id, data)
|
||||
nt.notify('stdout')
|
||||
end
|
||||
|
||||
local function on_exit(id, code, single)
|
||||
nt.notify('done')
|
||||
-- vim.api.nvim_buf_set_lines(0, 0, -1, false, text)
|
||||
end
|
||||
|
||||
-- local id = job.start({ vim.fn.exepath('prettier'), '--stdin-filepath', 't.md' }, {
|
||||
local id = job.start({ 'cat' }, {
|
||||
on_stdout = on_stdout,
|
||||
on_stderr = on_stderr,
|
||||
on_exit = on_exit,
|
||||
})
|
||||
|
||||
job.send(id, vim.api.nvim_buf_get_lines(0, 0, -1, false))
|
||||
job.send(id, nil)
|
||||
-- job.chanclose(id, 'stdin')
|
||||
-- job.stop(id)
|
||||
|
||||
-- local id2 = vim.fn.jobstart('cat', {
|
||||
-- on_stdout = on_stdout,
|
||||
-- on_stderr = on_stderr,
|
||||
-- on_exit = on_exit,
|
||||
-- })
|
||||
--
|
||||
-- vim.fn.chansend(id2, vim.api.nvim_buf_get_lines(0, 0, -1, false))
|
||||
-- vim.fn.jobstop(id2)
|
Loading…
x
Reference in New Issue
Block a user