Skip to content

Use rustfmt as equalprg in Vim/neovim #2840

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

Closed
andreyorst opened this issue Jul 12, 2018 · 1 comment
Closed

Use rustfmt as equalprg in Vim/neovim #2840

andreyorst opened this issue Jul 12, 2018 · 1 comment

Comments

@andreyorst
Copy link

I'm not sure where I should open this issue: here, or at rust.vim, but the problem I've encountered is about rustfmt itself.

Can I use rustfmt as equalprg in neovim or vim?
From :h equalprg

'equalprg' 'ep'		string	(default "")
			global or local to buffer |global-local|
	External program to use for "=" command.  When this option is empty
	the internal formatting functions are used; either 'lisp', 'cindent'
	or 'indentexpr'.  When Vim was compiled without internal formatting,
	the "indent" program is used.

So I've set it up with set equalprg=rustfmt but it doesn't work how I would expect it to.
For example:

  1. Create a project with $ cargo new
  2. Open src/main.rs in vim/neovim
  3. :set equalprg=rustfmt

Now you should be ready to format your code. So for example select all lines in the buffer with ggvG and hit =. Code will be formatted. However, If you select single line, the formatting is all wrong. Consider ( is a cursor):

fn main() {
    println!("Hello, world!");}

Pressing == wil result into:

fn main() {
println!("Hello, world!");
}

Default Vim behavior is different. It uses cindent, and code will be indented in the right way, because cindent is aware of surrounding code. However this is common situation, because clang-format does the same thing.
But there is more:

fn main() {println!("Hello, world!");
}

pressing == here will result into:

error: this file contains an un-closed delimiter
 --> <stdin>:1:13
  |
1 | fn main() {
  |             ^
  |
help: did you mean to close this delimiter?
 --> <stdin>:1:11
  |
1 | fn main() {
  |           ^

    println!("Hello, world!");
}

The code gets deleted, and replaced with error messages. The same situation will occur if you select only first two lines. This is not the case for clang-format, it still handles formatting well. Does rustfmt support partial formatting?

rustfmt 0.4.2-stable (febbb36 2018-04-12)
rust.vim commit: 7034eda0d96b89f2af35c90cb8db0ed52e7313d9
neovim:
NVIM v0.3.1-149-g44a284d71
Build type: RelWithDebInfo
LuaJIT 2.0.5

@nrc
Copy link
Member

nrc commented Jul 16, 2018

Do you know what Vim is sending to rustfmt? We use file-lines for this in the RLS (and I think some other integrations), that is imperfect, tracked in #1514. It might be however that Vim is only sending the line with the cursor on, in which case Rustfmt can't work because it needs a parseable subset of a program (which usually means a function or other module-level item).

The easiest solution is to send the whole file to Rust. Not sure what is possible in Vim.

Closing since I think this is covered by #1514 or is a Vim issue, but let me know if there is something else that can changed/added to Rustfmt add I can re-open.

@nrc nrc closed this as completed Jul 16, 2018
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