Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accepting a motion for vim.lsp.buf.range_formatting #14680

Closed
kovasap opened this issue May 30, 2021 · 12 comments
Closed

Accepting a motion for vim.lsp.buf.range_formatting #14680

kovasap opened this issue May 30, 2021 · 12 comments
Labels
enhancement feature request lsp

Comments

@kovasap
Copy link
Contributor

kovasap commented May 30, 2021

It looks like the range_formatting function takes in line positions that would allow it to format lines that are specified by a motion. I would love to have some kind of normal mode mapping to e.g. gl that allows me to do something like glip to format a paragraph. I feel like this is possible and maybe has already been done, but I'm at a loss for how to do it myself or where to find this functionality. Any pointers?

@kovasap kovasap added the enhancement feature request label May 30, 2021
@mjlbach mjlbach added the lsp label May 30, 2021
@kovasap
Copy link
Contributor Author

kovasap commented Jun 3, 2021

Any ideas here? This has probably already been done somewhere?

@mjlbach
Copy link
Contributor

mjlbach commented Jun 3, 2021

It hasn't been for any lsp functionality, given that you can already do this by first going into visual mode (I know that's not what you want) and then format_range, it's not a high priority for me, but happy to review any PR!

@shadmansaleh
Copy link
Contributor

You could easily do something like

local function format_range_operator()
  local old_func = vim.go.operatorfunc
  _G.op_func_formatting = function()
    local start = vim.api.nvim_buf_get_mark(0, '[')
    local finish = vim.api.nvim_buf_get_mark(0, ']')
    vim.lsp.buf.range_formatting({}, start, finish)
    vim.go.operatorfunc = old_func
    _G.op_func_formatting = nil
  end
  vim.go.operatorfunc = 'v:lua.op_func_formatting'
  vim.api.nvim_feedkeys('g@', 'n', false)
end

And map that map that function to what ever key you want to use . I haven't tested it though . I can't find server that does range formatting :P

@kovasap
Copy link
Contributor Author

kovasap commented Jun 17, 2021

To clarify, do you mean that you could add this to init.lua and then be able to use gmip in normal mode to format a paragraph?

local function format_range_operator()
  local old_func = vim.go.operatorfunc
  _G.op_func_formatting = function()
    local start = vim.api.nvim_buf_get_mark(0, '[')
    local finish = vim.api.nvim_buf_get_mark(0, ']')
    vim.lsp.buf.range_formatting({}, start, finish)
    vim.go.operatorfunc = old_func
    _G.op_func_formatting = nil
  end
  vim.go.operatorfunc = 'v:lua.op_func_formatting'
  vim.api.nvim_feedkeys('g@', 'n', false)
end
vim.api.nvim_set_keymap("n", "gm", "<cmd>lua format_range_operator()<CR>", {noremap = true})

This doesn't seem to work for me. Perhaps I missed something?

@shadmansaleh
Copy link
Contributor

-local function format_range_operator()
+function format_range_operator()

Make it a global function you can only map global functions the way you're mapping. Also check if your lasp server has range formatting capability set

@kovasap
Copy link
Contributor Author

kovasap commented Jun 18, 2021

Hmm, I think that helps, but now I get this error when I type gmip:

function format_range_operator()
  local old_func = vim.go.operatorfunc  -- ERROR: Error executing lua: <path to init.lua>: attampt to index field 'go' (a nil value)
  _G.op_func_formatting = function()
    local start = vim.api.nvim_buf_get_mark(0, '[')
    local finish = vim.api.nvim_buf_get_mark(0, ']')
    vim.lsp.buf.range_formatting({}, start, finish)
    vim.go.operatorfunc = old_func
    _G.op_func_formatting = nil
  end
  vim.go.operatorfunc = 'v:lua.op_func_formatting'
  vim.api.nvim_feedkeys('g@', 'n', false)
end
vim.api.nvim_set_keymap("n", "gm", "<cmd>lua format_range_operator()<CR>", {noremap = true})

My language server definitely supports range formatting - it works with buf_set_keymap("v", "gl", "<cmd>lua vim.lsp.buf.range_formatting()<CR>", opts) (in visual mode)!

@shadmansaleh
Copy link
Contributor

shadmansaleh commented Jun 18, 2021

Update nvim. You don't have the vim.opt commit.

You can map this in visual mode too.

 vim.api.nvim_set_keymap("n", "gm", "<cmd>lua format_range_operator()<CR>", {noremap = true})
+vim.api.nvim_set_keymap("v", "gm", "<cmd>lua format_range_operator()<CR>", {noremap = true})

What lsp server are you using ?

@kovasap
Copy link
Contributor Author

kovasap commented Jun 18, 2021

This works, thanks!! A internal company LSP for python.

@kovasap
Copy link
Contributor Author

kovasap commented Jun 18, 2021

It would be cool if this function was built into https://github.com/neovim/nvim-lspconfig and referenced in the docs : ). @mjlbach do you have an opinion about this?

@mjlbach
Copy link
Contributor

mjlbach commented Jun 18, 2021

It wouldn't go in lspconfig, lspconfig is (supposed) to be just configurations for language servers. It would probably go in vim.lsp.buf or vim.lsp.util. I feel like the solution as it stands is a little hacky, so I probably wouldn't feel comfortable merging it. You can put it in the nvim-lspconfig user tips section of the lspconfig wiki if you want though.

@kovasap
Copy link
Contributor Author

kovasap commented Jun 20, 2021

Done! https://github.com/neovim/nvim-lspconfig/wiki/User-contributed-tips

@neovim-discourse
Copy link

This issue has been mentioned on Neovim Discourse. There might be relevant details there:

https://neovim.discourse.group/t/format-a-text-object-using-lsp/3255/3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement feature request lsp
Projects
None yet
Development

No branches or pull requests

4 participants