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

Range formatting doesn't appear to work #1125

Open
bombela opened this issue Mar 20, 2023 · 6 comments
Open

Range formatting doesn't appear to work #1125

bombela opened this issue Mar 20, 2023 · 6 comments
Assignees

Comments

@bombela
Copy link

bombela commented Mar 20, 2023

What's the output of :CocInfo

    3 vim version: NVIM v0.8.1
    4 node version: v18.12.1
    5 coc.nvim version: 0.0.82-b7375d5f 2023-01-30 05:09:03 +0800
    6 coc.nvim directory: /home/bombela/.config/nvim/plugged/coc.nvim
    7 term: xterm-256color
    8 platform: linux

What's the output of :CocCommand rust-analyzer.serverVersion

[coc.nvim] rust-analyzer 0.4.1442-standalone

What's your coc-rust-analyzer version? You can get it from :CocList extensions

coc-rust-analyzer 0.72.1

In my coc-config I also have:

    3   "rust-analyzer.updates.checkOnStartup": "false",
    4   "rust-analyzer.rustfmt.enableRangeFormatting": true,
    5   "rust-analyzer.updates.channel": "nightly",

And :echo CocHasProvider('formatRange') returns v:true.

(by the way, "rust-analyzer.rustfmt.enableRangeFormatting": true enables the feature but "rust-analyzer": { "rustfmt.enableRangeFormatting": true } does not. Took me 45minutes to realize that).

Then I do :set formatexpr=CocAction('formatSelected'). Now I expect gq on a visual selection to format similar to RustFmt. Instead it formats the same as the default vim behavior. :CoInfo reports nothing of interest besides Request action: formatSelected [].

As a baseline, I can compare with rustfmt nightly and :'<,'>RustFmtRange.

Just to make sure things are happening at all, I can :set formatexpr=CocAction('wontwork'), and in this case it silently doesn't format anything. And :CoInfo reports Request error: wontwork [] Error: Action "wontwork" not exist.

I can also :set formatexpr=CocAction('format'), which does indeed format the whole file like RustFmt, confirming again that something is really executed.

So it appears that CocAction('formatSelected') with coc-rust-analyzer somehow falls-back to the default neovim formatting. I am not sure how to debug the issue further.

@fannheyward
Copy link
Owner

:set formatexpr=CocAction('formatSelected')

Reproduced, fail to do formatting.

xmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)

works as expected.

Will debug on the first one.

@fannheyward
Copy link
Owner

My usage with coc-format-selected, whole line or multiple lines:

  1. V to select whole line
  2. coc-format-selected
  3. the selected line will be formatted

with gq:

  1. V to select whole line, for example current line number is 21
  2. gq
  3. nothing happens

From coc, https://github.com/neoclide/coc.nvim/blob/94dc1051415eed1f0ffa39446ed22c63e3d8eb14/src/handler/format.ts#L197-L200

v:lnum,v:count,mode() returns 21, 0, n, coc stops to do formatting because count = 0.

another test, gggqG, v:lnum,v:count,mode() returns 1 0 n, coc stops cause count = 0.

Have no idea why vim returns v:count 0.

:h formatexpr document:

	The |v:lnum|  variable holds the first line to be formatted.
	The |v:count| variable holds the number of lines to be formatted.

@bombela
Copy link
Author

bombela commented Mar 21, 2023

Thank you for investigating! I confirm v:count is zero after running gq (over multiple lines). I guess when the format handler returns -1, neovim falls-back to the default?

I will see if I can debug some more. I wonder if vim behaves similar.

@fannheyward
Copy link
Owner

format handler returns -1, neovim falls-back to the default

:h formatexpr:

When the expression evaluates to non-zero Vim will fall back to using
the internal format mechanism.

v:count is zero after running gq (over multiple lines)

This is the key issue, have no idea why v:count is 0.

if vim behaves similar.

The same.

@bombela
Copy link
Author

bombela commented Mar 21, 2023

function! Test()
  echomsg "->" v:lnum v:count v:char mode()
  return 0
endfunction

:set formatexpr=Test()

v:lnum and v:count are both correct in the :messages output.

I don't really know how the async stuff in typescript/nodejs interacts with neovim. But I think what we observe is a race condition. The value of v:count is only valid during the synchronous execution of the expression in formatexp. After that, the selection is cleared, and v:count becomes zero.

@fannheyward
Copy link
Owner

@bombela set formatexpr=CocAction('formatSelected') works with clangd, but not rust-analyzer.

Both gq2j or V select two lines then gq, works as expected with clangd.

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

No branches or pull requests

2 participants